Compare commits

...

1148 Commits

Author SHA1 Message Date
ziyang.lb
c6f28eb386 fix bug : full ddl sqls should not assign to extra field but data field 2024-05-24 18:19:58 +08:00
ziyang.lb
a28806311a fix bug : full ddl sqls should not assign to extra field but data field 2024-05-24 17:53:55 +08:00
ziyang.lb
05562f1dfc migrate parser from druid to polardbx-parser(with version 5.4.19) 2024-05-24 13:43:31 +08:00
agapple
a98549ee0d Merge branch 'master' into feature/ziyang_migrate_parser 2024-05-22 21:05:31 +08:00
jianghang.loujh
aa05d8e2a0 reformat 2024-05-22 09:46:13 +08:00
leoloel
5ff6449620 fix issue #5127 escape key of json data (#5130) 2024-05-22 09:41:50 +08:00
ziyou
bbea802914 feat(es8): es8 支持证书认证 (#5106) 2024-04-28 09:54:53 +08:00
JZ
e2219c88dd add support for listener name which is described in https://pulsar.apache.org/docs/next/concepts-multiple-advertised-listeners/ (#5118) 2024-04-28 09:53:39 +08:00
jianghang.loujh
a92e61f5a9 fixed issue #5073 , optimize docker build 2024-04-15 18:52:42 +08:00
jianghang.loujh
eaacc01b77 fixed issue #5094 , support function unique index 2024-04-15 15:34:50 +08:00
ziyang.lb
a6d73ad16b migrate parser from druid to polardbx-parser 2024-04-06 21:54:34 +08:00
jianghang.loujh
caa46f3672 merge pull #5089 2024-04-03 10:45:29 +08:00
jianghang.loujh
c0ff058fe1 remove unnecessary bean copy 2024-03-18 15:58:53 +08:00
jianghang.loujh
059f21208d fixed issue #5066 , es7.x npe 2024-03-18 14:19:45 +08:00
jianghang.loujh
8ca900377a merge & reformat code 2024-03-08 11:58:46 +08:00
jackzlz
6dffcc8573 yml解析支持占位符 (#5045) 2024-03-08 11:56:30 +08:00
wbxlll
711971599f fix issue client-adapter.rdb模块在转换时间时丢失精度 #5052 (#5053)
* fix the issue that client-adapter.rdb module loses precision when converting microsencond time

* fix the issue that client-adapter.rdb module loses precision when converting to java.sql.Time or java.sql.Timestamp

* fix the issue that client-adapter.rdb module loses precision when converting to java.sql.Time or java.sql.Timestamp
2024-03-08 11:50:53 +08:00
Devin Zhang
87c7a95523 startup.sh支持JDK17启动 (#5060) 2024-03-08 11:48:16 +08:00
ChengDaqi2023
e255baff11 update com.rabbitmq:amqp-client 5.5.0 to 5.18.0 (#5050) 2024-02-26 19:25:48 +08:00
jianghang.loujh
d457cd835e fixed issue #4819 , optmize code 2024-02-05 17:01:33 +08:00
jianghang.loujh
cf9c64629e optimize split IPAndPort 2024-02-05 16:49:05 +08:00
jianghang.loujh
307547746c optimize test & connected mistake 2024-02-04 13:59:29 +08:00
jianghang.loujh
c7d5ed4ba1 fixed issue #5036 , connected mistake 2024-02-04 13:58:52 +08:00
jianghang.loujh
b9ed5caf05 format 2024-02-04 13:35:10 +08:00
jianghang.loujh
348d218120 fixed issue #5029 , add deserializer message 2024-02-04 13:28:27 +08:00
zoemak
e2a64daad8 fixed issue #5037 ,使用client-adapter.rdb模块进行ETL同步,源库为MySQL,数据库名有短横线,读取源数据时报SQL异常 (#5044) 2024-02-04 13:07:51 +08:00
jianghang.loujh
1413cc9196 fixed issue #4899 , druid SchemaRepository support quota 2024-01-15 15:14:11 +08:00
jianghang.loujh
04c11ec8eb fixed issue #5017 , json partial update fixed & format 2024-01-02 16:42:01 +08:00
Wang Minan
54145ced5e fix parser failed when binlog_row_value_options=partial_json (#5018)
* 修改json部分更新的问题

* 保证after-image的情况下位点回退完整
2024-01-02 10:44:40 +08:00
agapple
fb35dd4254 Update README.md 2023-12-29 12:12:22 +08:00
jianghang.loujh
e233bec66a fixed issue #5012 , support mariadb 11 for Q_CHARACTER_SET_COLLATIONS 2023-12-29 12:08:28 +08:00
jianghang.loujh
67e0928d80 fixed security bugfix #4941 , process auth failed 2023-12-22 10:29:38 +08:00
jianghang.loujh
93dac2d335 format clickhouse adapter code 2023-12-04 09:46:23 +08:00
xander-os
9baeff55e4 enhance clickhouse support (#4957) 2023-12-04 09:34:43 +08:00
Devin Zhang
ca79258e4f support rabbitmq ssl (#4965) 2023-12-04 09:28:26 +08:00
jianghang.loujh
0e4c5c40d7 format code 2023-11-09 15:35:37 +08:00
e345
c65477d97a loadVersionComment() add logger.warn info (#4943) 2023-11-09 15:31:33 +08:00
mask
fc3cfc5c0c Fixed bug where cp -f actually failed, (#4942)
because the symlink already existed.
2023-11-09 15:31:04 +08:00
jianghang.loujh
b4074206ca fixed issue #4940 , support percona 8.0.33 2023-11-08 16:37:24 +08:00
jianghang.loujh
98677c5bc8 fixed issue #4941 , remove default passwd 2023-11-08 10:58:43 +08:00
PeanutVvl
2c7e918f30 将 Logback 升级到 1.2.9 及以上版本 (#4934)
Co-authored-by: wangsc <Asdf1234>
2023-11-07 14:42:56 +08:00
jianghang.loujh
163f719971 fixed issue #4923 , support fastJSON Feature.LargeObject 2023-11-03 12:39:53 +08:00
jianghang.loujh
55a5e7592b fixed issue #4930 , check embeddedServerstate 2023-11-03 11:04:11 +08:00
jianghang.loujh
259008a7cd update config 2023-11-03 10:39:17 +08:00
marun
26ba84e27e Update KafkaCanalConnector.java (#4927)
update fastjson to fastjson2
2023-11-03 10:36:44 +08:00
jianghang.loujh
c8ef9552ec fixed #4907 , reset tsdb build context 2023-10-13 14:05:15 +08:00
jianghang.loujh
bff394042a fixed testcase 2023-10-09 14:31:46 +08:00
jianghang.loujh
b322201889 [maven-release-plugin] prepare for next development iteration 2023-10-09 14:27:37 +08:00
jianghang.loujh
ea8949298f [maven-release-plugin] prepare release canal-1.1.7 2023-10-09 14:27:33 +08:00
dack-su
ba924b9f1d update org.postgresql:postgresql 42.3.3 to 42.5.1 (#4898) 2023-10-09 13:46:20 +08:00
jianghang.loujh
7e0061fe93 build.sh add platform 2023-10-08 19:31:10 +08:00
jianghang.loujh
6440b744f2 fixed arm64 stack size too small, upgrade all to 1m 2023-10-08 18:55:06 +08:00
jianghang.loujh
066b022bb3 fixed arm64 , support mysql 8.0 2023-10-08 17:51:56 +08:00
jianghang.loujh
738f41049f fixed arm64 stack size too small, upgrade to 1m 2023-10-08 14:39:59 +08:00
jianghang.loujh
0f6b9d156a fixed concurrent set properties NPE 2023-10-07 21:54:34 +08:00
jianghang.loujh
ed754b5203 fixed issue #4884, osbase/osadmin image support amd64/arm64 2023-10-07 21:54:00 +08:00
小鹏
11f89163c1 fixed issue #4813, support metric.port = -1 (#4891) 2023-10-07 13:15:07 +08:00
cooper lee
cda330e49e Fix Configuration property name '-id' is not valid on canal 1.1.7 alpha 3 #4879 (#4887)
* Fix Configuration property name '-id' is not valid

* Fix Configuration property name '-id' is not valid
读取原配置文件
2023-09-21 10:53:47 +08:00
jianghang.loujh
f9f810226d fixed issue #4869 , support admin tsdb config 2023-09-11 10:57:43 +08:00
jianghang.loujh
d4a09704f2 optimize gtid 2023-09-07 09:48:58 +08:00
jianghang.loujh
34e9440383 fixed issue #4864 , connector.disconnect optimize 2023-09-04 19:34:06 +08:00
weirhp
d623bea71a 解决rdb下有多个配制,会导致配置相互覆盖的问题 (#4560)
恩baseProperties这个变量是共享的,不能修改这个变量的属性值。要不后续的配置都会改变。关联issue为4355
2023-09-04 17:23:26 +08:00
jianghang.loujh
5ea9259f0d upgrade kafka-client 2.4.0 2023-09-04 14:27:05 +08:00
jianghang.loujh
a216b55010 fixed password length 6-digit limit 2023-09-02 11:12:09 +08:00
jianghang.loujh
2786e06ccf format es8 2023-09-01 19:58:23 +08:00
ymz
63dfbf65df es8x adapter (#4640) 2023-09-01 19:56:03 +08:00
jianghang.loujh
d90066e01b upgrade spring cloud & spring boot version 2023-09-01 19:51:49 +08:00
jianghang.loujh
69cfbabb10 upgrade spring cloud & spring boot version 2023-09-01 17:20:26 +08:00
jianghang.loujh
ab30f3bd8d fixed issue #3350 ,upgrade netty 2023-09-01 14:12:35 +08:00
jianghang.loujh
681d03fbe7 upgrade dependency version for CVE 2023-09-01 13:59:05 +08:00
jianghang.loujh
f13cc4ee9f fixes issue #4388 , support mariadb 10.x log_bin_compress 2023-09-01 13:42:49 +08:00
jianghang.loujh
252ca0279f fixes issue #4388 , support mysql 8.0.20+ TransactionPayloadLogEvent parse 2023-08-25 16:57:22 +08:00
jianghang.loujh
7241af84f7 fixed issue #4742 , format 2023-08-22 17:52:38 +08:00
zard
159457cccd very very major:Adapter rdb bug fix (#4742)
* 异常点描述1

* 问题描述

* bug fix

rdb yml文件 编码格式问题,导致所有outerAdapter初始化失败;
kafka消息空跑,数据全都丢失 问题 fix
2023-08-22 17:50:12 +08:00
jianghang.loujh
d8a70d0c2f fixed issue #4822 , fix connection close 2023-08-22 17:32:42 +08:00
CVEDetect
ec247114fd Update pom.xml (#4591) 2023-08-22 17:25:13 +08:00
elizwy
f067f761c7 fix issue 4806, make Common.init success (#4830)
Co-authored-by: eli.zwy <wenyang.zhang@ipinyou.com>
2023-08-22 17:21:50 +08:00
jianghang.loujh
d4c8780f26 fixed issue #4786 , revert compact BigDecimal optimize 2023-08-22 17:14:01 +08:00
jianghang.loujh
894ef6e610 fixed issue #4659 , gtid NPE 2023-07-29 09:57:52 +08:00
jianghang.loujh
cc75d3dda4 fixed issue #4706 , upgrade fastjson 2.0.31 2023-07-29 09:12:52 +08:00
jianghang.loujh
d8169cbf71 fixed issue #4813, support metric.port = -1 2023-07-28 13:38:47 +08:00
jianghang.loujh
fccc6bc816 fixed #4665 2023-07-28 13:25:05 +08:00
jianghang.loujh
97aa441bca fixed PR format 2023-07-28 13:20:56 +08:00
高原
b8c2a757a0 增加对mysql的caching_sha2_password认证插件fullauth流程支持 (#4767) 2023-07-18 16:33:40 +08:00
TENET
c8de48bbd5 fix typo (#4720) 2023-07-18 16:21:44 +08:00
jianghang.loujh
08239ef23f Merge branch 'master' of github.com:alibaba/canal 2023-07-18 16:17:10 +08:00
施昱平
04a2b6f941 修复从远程下载rds-binlog文件到本地时响应头获取不到Content-Length导致的NPE的问题 (#4760) 2023-07-18 16:16:50 +08:00
jianghang.loujh
5f667c3574 Merge branch 'master' of github.com:alibaba/canal 2023-07-18 16:11:24 +08:00
toywei
bfb8cf4190 Update Dockerfile (#4775)
Set the Author field of the generated images. This instruction has been deprecated in favor of LABEL.
2023-07-18 16:10:07 +08:00
jianghang.loujh
18c38ee057 upgrade fastjson & druid 2023-04-23 09:54:01 +08:00
SofiaChenBot
82b3aed62b Update README.md (#4688) 2023-04-20 11:28:33 +08:00
lulu2panpan
a04a1912a8 add support for polardbx multi binlog streams (#4660)
* AbstractCanalInstance的subscribeChange方法,增加对AbstractEventParser的类型判断,以支持用户的自定义CanalEventParser

* MysqlEventParser对Gtid模式的处理需要考虑兼容性,支持系统平滑的从非gtid模式升级为gtid模式

* add support for polardbx multi binlog streams #4657

* support auto generate instance names #4657
2023-03-23 13:46:10 +08:00
Smile-cmd
5d7d19fdb1 增加rabbitmq配置,以持久化方式投递消息 (#4644)
Co-authored-by: wangheng <760261296@qq.com>
2023-03-16 18:42:37 +08:00
fuzhong-jiye
9edbe7e827 支持 mysql_clear_password 明文密码模式, 在一些开发、测试环境可能遇上。 (#4628)
Co-authored-by: zhongfu <zhongfu@tesla.com>
2023-03-16 18:39:11 +08:00
starrywu
b52c5d149b Update LogEventConvert.java (#4653)
fixed issue #4652,  解决mysql中类型为MEDIUMTEXT的字段的javaType在不同场景的解析不一致的问题
2023-03-16 17:47:21 +08:00
Frank Zhao
aada80ba38 doc: update readme (#4589)
Add contribution leaderboard badge into README file.

Signed-off-by: frank-zsy <syzhao1988@126.com>
2023-02-07 17:10:39 +08:00
jianghang.loujh
a10698e4a8 fixed issue #4491 , upgrade druid 1.2.15 2023-01-04 13:40:39 +08:00
jianghang.loujh
9d0a37241f fixed desc table case insensitive 2022-12-26 14:40:58 +08:00
dengyangguang
41a2a87a91 fix issue #4267 old和data长度不一样而产生的下标越界异常 (#4504) 2022-12-23 16:13:42 +08:00
shicongyang
62c4333790 canal中的flatMessage中添加一个参数,记录gtid #4509 (#4521) 2022-12-23 16:04:46 +08:00
rewerma
ea8fb5e5b8 修复client中的kafka consumer消费回滚的bug (#4532) 2022-12-14 19:45:25 +08:00
rewerma
cd798b71e9 add proxy for SPI (#4520)
* 测试类报错

* add proxy for SPI
2022-12-06 17:35:30 +08:00
rewerma
b937ee613d Revert 4516 feature/macy (#4519)
* 修复测试类报错 (#4516)

* optimize YAML config loader (#4332)

* fix bug BASE TABLE as table name (#4217)

* fix issues#4328 (#4329)

* docs: add nodejs canal client support (#4260)

Co-authored-by: zhangxunwei <zhangxunwei@dxy.cn>

* fix destination not encoded (#4279)

* 修复Canal指定时间戳启动失效,总是从最新的点位开始同步问题 (#4348)

* 支持用户自定义的CanalAlarmHandler

* RowsLogEvent增加对TableMapLogEvent判空检查,防止NPE异常

* 修复Canal指定时间戳启动失效,总是从最新的点位开始同步问题, issue: #4347

Co-authored-by: 云时 <mingya.wmy@alibaba-inc.com>

* fixed 4334 , support jdk8/jdk11

* fixed issue #4266 , typo

* fixed issue #4243 , support auto register for cluster = null

* fixed issue #4225 , support mysql version >= 8.0.26 heartbeat v2

* fixed issue #4308 , support query_log_event for maraiadb 10.10.1

* ignore compression event

* support jdk11

* support druid 1.2.12

* fixed mariadb 10.x

* sync canal-template.properties

* update fastjson & druid version (#4406)

* 修复升级2.0.4导致兼容的问题

* update druid & fastjson version

* update fastjson version

* update druid & fastjson version

* meta.dat文件数据丢失 (#4397)

* update fastjson & druid version (#4438)

* 局部变量线程安全,优先使用StringBuilder替换StringBuffer (#4472)

Co-authored-by: 夏亮 <xialiang@newerabc.com>

* 1. CanalController stop 需要同时将 embededCanalServer.stop (#4477)

2. ServerRunningMonitor 线程池未正常回收,线程池管理与 start/stop保持一致

* vuln-fix: Use HTTPS instead of HTTP to resolve dependencies (#4437)

This fixes a security vulnerability in this project where the `build.gradle`
files were configuring Gradle to resolve dependencies over HTTP instead of
HTTPS.

Weakness: CWE-829: Inclusion of Functionality from Untrusted Control Sphere
Severity: High
CVSSS: 8.1
Detection: OpenRewrite

Reported-by: Jonathan Leitschuh <Jonathan.Leitschuh@gmail.com>
Signed-off-by: Jonathan Leitschuh <Jonathan.Leitschuh@gmail.com>

Bug-tracker: https://github.com/JLLeitschuh/security-research/issues/9


Co-authored-by: Moderne <team@moderne.io>

Co-authored-by: Moderne <team@moderne.io>

* fix_ETL同步mysql关键字报错 (#4346)

Co-authored-by: foleyang <foleyang@cogobuy.com>

* optimize code

* use compact BigDecimal

* performance optimize , 1. cache string names 2. cache Charset

* performance optimize ,cache integer/long valueof

* 测试类报错

Co-authored-by: gongchangyou <gongchangyou@gmail.com>
Co-authored-by: ChanaLii <316529035@qq.com>
Co-authored-by: zhangxunwei <zhangxunweia@gmail.com>
Co-authored-by: zhangxunwei <zhangxunwei@dxy.cn>
Co-authored-by: tianpeidong <39491687+tianpeidong@users.noreply.github.com>
Co-authored-by: dataccs <dataccs@163.com>
Co-authored-by: 云时 <mingya.wmy@alibaba-inc.com>
Co-authored-by: jianghang.loujh <jianghang.loujh@alibaba-inc.com>
Co-authored-by: 温绍锦 <shaojin.wensj@alibaba-inc.com>
Co-authored-by: noaso <noasoso@gmail.com>
Co-authored-by: HumanPassenger <40585855+HumanPassenger@users.noreply.github.com>
Co-authored-by: 夏亮 <xialiang@newerabc.com>
Co-authored-by: 华仔 <591327356@qq.com>
Co-authored-by: Jonathan Leitschuh <jonathan.leitschuh@gmail.com>
Co-authored-by: Moderne <team@moderne.io>
Co-authored-by: 杰锅不是锅 <1105568074@qq.com>
Co-authored-by: foleyang <foleyang@cogobuy.com>

* Revert "修复测试类报错 (#4516)"

This reverts commit d899981354.

Co-authored-by: gongchangyou <gongchangyou@gmail.com>
Co-authored-by: ChanaLii <316529035@qq.com>
Co-authored-by: zhangxunwei <zhangxunweia@gmail.com>
Co-authored-by: zhangxunwei <zhangxunwei@dxy.cn>
Co-authored-by: tianpeidong <39491687+tianpeidong@users.noreply.github.com>
Co-authored-by: dataccs <dataccs@163.com>
Co-authored-by: 云时 <mingya.wmy@alibaba-inc.com>
Co-authored-by: jianghang.loujh <jianghang.loujh@alibaba-inc.com>
Co-authored-by: 温绍锦 <shaojin.wensj@alibaba-inc.com>
Co-authored-by: noaso <noasoso@gmail.com>
Co-authored-by: HumanPassenger <40585855+HumanPassenger@users.noreply.github.com>
Co-authored-by: 夏亮 <xialiang@newerabc.com>
Co-authored-by: 华仔 <591327356@qq.com>
Co-authored-by: Jonathan Leitschuh <jonathan.leitschuh@gmail.com>
Co-authored-by: Moderne <team@moderne.io>
Co-authored-by: 杰锅不是锅 <1105568074@qq.com>
Co-authored-by: foleyang <foleyang@cogobuy.com>
2022-12-06 16:43:25 +08:00
rewerma
9c6f6f5cdf 测试类报错 (#4518) 2022-12-06 16:40:11 +08:00
jianghang.loujh
869e831b04 performance optimize ,cache integer/long valueof 2022-11-16 19:41:41 +08:00
jianghang.loujh
f7a4979b15 performance optimize , 1. cache string names 2. cache Charset 2022-11-16 17:33:02 +08:00
jianghang.loujh
afef45500e use compact BigDecimal 2022-11-16 16:14:11 +08:00
jianghang.loujh
4c7cdbc7f3 optimize code 2022-11-16 10:27:14 +08:00
杰锅不是锅
279d503cf4 fix_ETL同步mysql关键字报错 (#4346)
Co-authored-by: foleyang <foleyang@cogobuy.com>
2022-11-16 10:24:56 +08:00
Jonathan Leitschuh
272b1d5d11 vuln-fix: Use HTTPS instead of HTTP to resolve dependencies (#4437)
This fixes a security vulnerability in this project where the `build.gradle`
files were configuring Gradle to resolve dependencies over HTTP instead of
HTTPS.

Weakness: CWE-829: Inclusion of Functionality from Untrusted Control Sphere
Severity: High
CVSSS: 8.1
Detection: OpenRewrite

Reported-by: Jonathan Leitschuh <Jonathan.Leitschuh@gmail.com>
Signed-off-by: Jonathan Leitschuh <Jonathan.Leitschuh@gmail.com>

Bug-tracker: https://github.com/JLLeitschuh/security-research/issues/9


Co-authored-by: Moderne <team@moderne.io>

Co-authored-by: Moderne <team@moderne.io>
2022-11-16 09:59:27 +08:00
华仔
fa0c08c170 1. CanalController stop 需要同时将 embededCanalServer.stop (#4477)
2. ServerRunningMonitor 线程池未正常回收,线程池管理与 start/stop保持一致
2022-11-16 09:57:59 +08:00
HumanPassenger
10ff148aba 局部变量线程安全,优先使用StringBuilder替换StringBuffer (#4472)
Co-authored-by: 夏亮 <xialiang@newerabc.com>
2022-11-16 09:55:18 +08:00
温绍锦
571fa0d6fb update fastjson & druid version (#4438) 2022-11-16 09:49:55 +08:00
noaso
aa29f12d96 meta.dat文件数据丢失 (#4397) 2022-11-16 09:44:11 +08:00
温绍锦
3bceb07c44 update fastjson & druid version (#4406)
* 修复升级2.0.4导致兼容的问题

* update druid & fastjson version

* update fastjson version

* update druid & fastjson version
2022-09-15 14:57:59 +08:00
jianghang.loujh
c16d6e7729 sync canal-template.properties 2022-09-13 23:33:39 +08:00
jianghang.loujh
fb6981356f fixed mariadb 10.x 2022-09-13 22:28:49 +08:00
jianghang.loujh
c055737e24 support druid 1.2.12 2022-09-13 15:03:30 +08:00
jianghang.loujh
ef7e21e4b2 support jdk11 2022-09-01 18:27:19 +08:00
jianghang.loujh
ce916ee407 ignore compression event 2022-09-01 18:27:08 +08:00
jianghang.loujh
92758b8c87 fixed issue #4308 , support query_log_event for maraiadb 10.10.1 2022-09-01 17:35:29 +08:00
jianghang.loujh
7585d9c98b fixed issue #4225 , support mysql version >= 8.0.26 heartbeat v2 2022-09-01 16:14:55 +08:00
jianghang.loujh
9d37bb87b7 fixed issue #4243 , support auto register for cluster = null 2022-09-01 13:31:01 +08:00
jianghang.loujh
2faecec749 fixed issue #4266 , typo 2022-09-01 13:02:02 +08:00
jianghang.loujh
0ef7b28c03 fixed 4334 , support jdk8/jdk11 2022-09-01 11:15:39 +08:00
dataccs
41bf3e2289 修复Canal指定时间戳启动失效,总是从最新的点位开始同步问题 (#4348)
* 支持用户自定义的CanalAlarmHandler

* RowsLogEvent增加对TableMapLogEvent判空检查,防止NPE异常

* 修复Canal指定时间戳启动失效,总是从最新的点位开始同步问题, issue: #4347

Co-authored-by: 云时 <mingya.wmy@alibaba-inc.com>
2022-08-24 14:21:47 +08:00
tianpeidong
4d4199c801 fix destination not encoded (#4279) 2022-08-11 11:31:28 +08:00
zhangxunwei
b390e74a18 docs: add nodejs canal client support (#4260)
Co-authored-by: zhangxunwei <zhangxunwei@dxy.cn>
2022-08-11 10:48:54 +08:00
ChanaLii
72c0e24cfd fix issues#4328 (#4329) 2022-08-11 10:44:01 +08:00
gongchangyou
3dc86330a8 fix bug BASE TABLE as table name (#4217) 2022-08-11 10:41:01 +08:00
rewerma
eee73dc4b1 optimize YAML config loader (#4332) 2022-08-01 20:15:14 +08:00
jianghang.loujh
a96db39420 add polardb-x parser test 2022-06-13 09:39:29 +08:00
温绍锦
bac1d543f1 update fastjson & druid version (#4224)
* 修复升级2.0.4导致兼容的问题

* update druid & fastjson version
2022-06-13 09:31:46 +08:00
jianghang.loujh
753fad6639 fixed issue #4216 , support polardb-x show tables 2022-06-10 13:36:39 +08:00
jianghang.loujh
bc4dceea1a fixed issue #4216 , support polardb-x show databases 2022-06-10 11:37:52 +08:00
温绍锦
7aaee7b439 修复升级2.0.4导致兼容的问题 (#4202) 2022-05-30 10:29:38 +08:00
温绍锦
e19bf1ecff Fastjson2 compatible fix (#4189)
* update fastjson2 version, 2.0.2 -> 2.0.3

* update fastjson & druid version

* bug fix for fastjson2 compatible
2022-05-25 10:22:26 +08:00
jianghang.loujh
a99dc0cbe8 fixed testcase 2022-05-24 11:18:40 +08:00
jianghang.loujh
7b8ff04d20 [maven-release-plugin] prepare for next development iteration 2022-05-24 10:26:12 +08:00
jianghang.loujh
7ee246ca5a [maven-release-plugin] prepare release canal-1.1.6 2022-05-24 10:26:06 +08:00
jianghang.loujh
54c645f315 fixed test failed 2022-05-24 10:12:26 +08:00
jianghang.loujh
6c81ab6fdc fixed compiler error 2022-05-24 10:08:02 +08:00
jianghang.loujh
99aefaa118 support mysql 8.0 transaction_payload_event 2022-05-23 23:23:52 +08:00
jianghang.loujh
e2248b3d35 update phoenix pom.xml 2022-05-23 19:30:19 +08:00
jianghang.loujh
eef1ee85fb fixed issue #4014, support java8 & java11 G1 GC 2022-05-23 18:23:31 +08:00
温绍锦
7dfec19c68 update druid & fastjson2 version (#4183)
* update fastjson2 version, 2.0.2 -> 2.0.3

* update fastjson & druid version
2022-05-23 10:03:41 +08:00
jianghang.loujh
05a52f1bd3 upgrade log4j version 2022-05-20 16:58:20 +08:00
jianghang.loujh
fb0f274ba8 fixed logger 2022-05-20 16:09:53 +08:00
jianghang.loujh
d71a208123 fixed issue #4178 , support -00:00:00.12 2022-05-20 10:37:53 +08:00
jianghang.loujh
656a1d23c2 instance.properties demo 2022-05-19 19:56:50 +08:00
jianghang.loujh
a574b91fdf fixed #3976 , support LogEvent.MYSQL_TYPE_TYPED_ARRAY 2022-05-19 19:53:54 +08:00
jianghang.loujh
e41e903984 fixed issue #3538 , compatiable mysql8.0 filed meta 2022-05-17 17:17:32 +08:00
jianghang.loujh
4a22d72ef4 fixed issue #4018, fixed CanalInstanceWithManager thread-safe 2022-05-16 19:46:34 +08:00
jianghang.loujh
b7eff723a3 fixed issue #4027, CanalServerWithEmbedded.get support newList 2022-05-16 19:41:46 +08:00
jianghang.loujh
9b9cfe4037 fixed issue #4152, TableMetaTSDB support canal.instance.filter.query.ddl=true 2022-05-16 17:25:43 +08:00
jianghang.loujh
ee51f338e0 fixed outAdapterkey autoGen 2022-05-13 15:13:14 +08:00
zhuchao941
4315f203a2 repair issue #3401 (#3923)
* 解决OutAdapter单例导致的问题,如 1.多个es7 outAdapter的多线程问题(共享同一个es bulk request),2.多个es7 outAdapter共用一份es配置问题

* 1. 优化adapter和监听器之间的代码结构
2. 监听器只处理匹配的配置文件
3. bugfix-es adapter配置文件回调时漏写esVersion
理论上一个adapter实例对应一个config配置文件

Co-authored-by: agapple <jianghang.loujh@alibaba-inc.com>
2022-05-13 15:02:06 +08:00
jianghang.loujh
b12945d4a9 format yml 2022-05-13 14:39:57 +08:00
Treeyh
885f05fb6a 支持定义rocketmq client日志路径,及修复一些bug (#3229)
* 修复接入阿里云RocketMq no route info for this topic 问题

* 支持deployer同步rocketmq时定义rocketmq client日志路径

* 支持deployer同步rocketmq时定义rocketmq client日志路径

* 回退guava版本号,解决adapter的java.lang.NoSuchMethodError: com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor()异常

* 解决adapter启动报com.alibaba.druid.pool.DruidDataSource cannot be cast to com.alibaba.druid.pool.DruidDataSource异常。

* 支持rocketmq client 配置日志路径

Co-authored-by: hai.yu <hai.yu@snowballtech.com>
Co-authored-by: agapple <jianghang.loujh@alibaba-inc.com>
2022-05-13 14:39:29 +08:00
ChengTie(鐵手)
591126ee6b update (#3326) 2022-05-13 14:37:17 +08:00
He Wang
af432bf10a fix data truncated for column issue for type year (#3866) 2022-05-13 14:33:06 +08:00
jumao
b532e90ff4 ESAdapter Support the same instance cross -library query (#4161)
* ESAdapter Support the same instance cross -library query

* fix null point ex
2022-05-13 14:31:09 +08:00
xiaoyu.zhang
e48bc35f35 通过索引别名获取mapping,返回数据为真实索引,而不是别名,导致mappings.get(index).get(type)报空指针异常 (#4122) 2022-05-13 14:28:53 +08:00
He Wang
11a5f2a0fa add druid stat filter (#3985) 2022-05-13 14:24:37 +08:00
He Wang
c775478a56 set backtick by DbType (#3984)
Co-authored-by: agapple <jianghang.loujh@alibaba-inc.com>
2022-05-13 14:23:40 +08:00
He Wang
bd1f91cd9c fix sync order in RdbMirrorDbSyncService (#3928) 2022-05-13 14:19:40 +08:00
jianghang.loujh
67e85d201c remove client adapter Docker 2022-05-13 12:46:12 +08:00
wanglei
6965726dfe fix bug #2023 (#3871)
* fix bug #2023

* 配置canal-adapter,docker生成脚本
2022-05-13 12:39:43 +08:00
willmao
c0001afe8f use hostname if register name not set (#3968) 2022-05-13 12:24:33 +08:00
xiayingfeng
977031a666 Improve MAVEN build Performance (#4055) 2022-05-13 12:23:33 +08:00
zhangshaoning
bd3224eea1 Upgrade reference log4j package version (#4017) 2022-05-13 12:22:45 +08:00
jianghang.loujh
33733aef25 fixed compatible and code format 2022-05-13 11:59:57 +08:00
zhangjukai
25be0259a4 Some tweaks for pulsarmq-connector (#4060)
* 1. Add the com.alibaba.otter.canal.connector.core.spi.CanalMsgConsumer file to the META-INF/canal directory under the pulsarmq-connector project
2. Introduce pulsar-client-admin for Canal to automatically create multi-partition topics
3. Add the judgment that roleToken is null
4. The disconnect method in CanalPulsarMQConsumer removes this.pulsarMQConsumer.unsubscribe();, this code will cause data loss during stop
5. When getting Pulsar messages, they are all processed as flat messages, because CanalMessageSerializerUtil.deserializer(data) will deserialize exceptions
6. Use groupId as subscriptName, without the pulsarmq.subscriptName parameter, the entire adapter will be the same subscriber name using pulsarmq.subscriptName

* 逻辑优化

* 代码优化

* 针对pulsar的调整

* 恢复代码

* 恢复代码

* 处理Producer失效的情况
2022-05-13 11:41:50 +08:00
liteng2430
8114d77a20 Add verification: the user can set a password with a length of less than 6 digits when updating the password, but the password length must be greater than or equal to 6 digits when logging in to canal admin, so the length verification function when updating the login password is added (#4103) 2022-05-13 11:34:36 +08:00
ZhangJian He
571e7f4e25 fix ojdbc6 wrong corrinator (#4132) 2022-05-13 11:33:42 +08:00
温绍锦
ead91433d7 fastjson update 1.x to 2.0.2 (#4160) 2022-05-13 11:32:47 +08:00
xiaoma20082008
bac016f89e <feat>: support visibility columns (#3976) 2022-05-13 11:30:19 +08:00
willmao
8804647c30 avoid print password when logging (#3969) 2022-05-13 11:28:05 +08:00
mclubing
2623d08b8c rdb配置不支持yaml后缀文件 (#3964)
增加rdb配置支持yaml后缀文件
2022-05-13 11:26:04 +08:00
wuare
622fed84ce fixed logger name (#3887) 2022-05-13 11:24:00 +08:00
He Wang
9f5e8fd1c4 rollback guava version in adapter module (#3880) 2022-05-13 11:23:30 +08:00
Junwang Zhao
88d472ef1e move protocol test to protocol test directory (#3864)
1. move the protocol test to right directory
2. fix wrong string format params count

Signed-off-by: 元组 <zhaojunwang.zjw@alibaba-inc.com>
2022-05-13 11:16:06 +08:00
Aiden.Ao
2987d08161 fix issue #3144 (#3712) 2022-05-13 11:09:09 +08:00
tuple
b54bea5e33 polish the code thus make it more stable (#3855)
Signed-off-by: 元组 <zhaojunwang.zjw@alibaba-inc.com>
2021-10-11 14:46:22 +08:00
jianghang.loujh
c42ba95eed fixed pulsarmq package 2021-10-09 18:06:34 +08:00
jianghang.loujh
b48c434ffd fixed phoenix version 2021-10-09 17:52:13 +08:00
jianghang.loujh
2c892fce9b fixed issue #3484 , fixed bat script 2021-10-09 17:39:22 +08:00
jianghang.loujh
3bb49e19d2 fixed issue #3576, stop exporter 2021-10-09 17:29:23 +08:00
jianghang.loujh
f26b84ffc2 fixed issue #3829 , kafka connector support k8s env 2021-10-09 16:31:59 +08:00
364102729
0a2254eeaf add tablestore adapter (#3754)
* add tablestore adapter

* add tablestore adapter

* fix bug add add log when etl fail

* fix bug,tinyint(1)以及rowupdatechange

Co-authored-by: agapple <jianghang115@gmail.com>
2021-10-09 16:06:13 +08:00
jianghang.loujh
40d840375f fixed MR 2021-10-09 15:59:12 +08:00
Chad2li
5b6fd8094a 增加Apache Pulsar MQ支持 (#3791)
* done pulsarmq

* del pulsar consumer

* pulsar partition

* done pulsar consumer&connector

* update pulsar-client version to 2.8.1

Co-authored-by: agapple <jianghang115@gmail.com>
2021-10-09 15:51:45 +08:00
mikoto
4ce401d219 fix: 多destination的场景下只能生效一个 (#3772) 2021-10-09 15:38:26 +08:00
Jonathan Schneider
de95a6a128 refactor: Use Java standard library instead of Guava (#3708)
Co-authored-by: Moderne <team@moderne.io>

Co-authored-by: Moderne <team@moderne.io>
2021-10-09 15:33:37 +08:00
happyrita
9e11c3c018 定时保存snapshot到DB的逻辑中,schema名称获取错误,在有配置canal.instance.filter.regex时,由于对应的table无法被匹配中,导致compareTableMetaDbAndMemory方法不被执行 (#3693)
* 避免重复订阅zk变更状态

* Update DatabaseTableMeta.java

获取schema的名称

* Update CanalController.java
2021-10-09 15:32:20 +08:00
arthasking123
d67bea8f3d repair issue #3678,#3680 (#3684)
* repair issue #3678,#3680

* repair issue #3678,#3680
2021-10-09 15:30:32 +08:00
kkjinping
997957d6e0 新增配置 canal.mq.enableDynamicQueuePartition,获取topic对应的队列的数量为分区的数量,以支持动态队列的场景(如阿里云的rocketmq,无法人工设置队列数量,可能会动态伸缩) (#3670) 2021-10-09 15:26:23 +08:00
tanpenggood
ea20076a32 fix: rowChange typo (#3593) 2021-10-09 15:23:36 +08:00
dinosaur
2550d8eb65 Connection is already closed fix (#3587) 2021-10-09 14:54:05 +08:00
nick
31a0fdc807 add note (#3550) 2021-10-09 14:53:28 +08:00
lanicc
d79431c7e5 fix typo (#3532) 2021-10-09 14:53:00 +08:00
ruanjl
911711248c 修复rds高可用主从切换和oss相关问题 (#3480)
* 修复rds oos 拉取的binlog 的消费逻辑以及本地消费到直连消费的逻辑衔接

* 去除无用代码
2021-10-09 14:51:41 +08:00
spark
63407dc570 canal adapter phoenix (#3290)
* canal adapter phoenix

* canal adapter phoenix

* canal adapter phoenix

* canal adapter phoenix

* canal adapter phoenix

* canal adapter phoenix

* canal adapter phoenix

Co-authored-by: lihuav2017 <lihua@able-elec.com>
2021-10-09 14:37:11 +08:00
flowell
3c20fd09ad fix issue #3839: 修复alter table character set类型DDL语句解析BUG (#3840) 2021-10-09 14:28:56 +08:00
ChenZhangg
eef3bd92ba Improve MAVEN build Performance (#3851)
Co-authored-by: Chen Zhang <340355960@qq.com>
2021-10-09 14:26:26 +08:00
agapple
474063af3b fixed issue #3494 , polardb-x 2.0 cdc support implicit_id/varaibles 2021-04-28 13:42:55 +08:00
agapple
5cc85ff2de [maven-release-plugin] prepare for next development iteration 2021-04-19 15:48:20 +08:00
agapple
64862503ba [maven-release-plugin] prepare release canal-1.1.5 2021-04-19 15:48:09 +08:00
agapple
f9e0dc7daa fixed testcase 2021-04-19 15:15:10 +08:00
agapple
0c399509a9 upgrade druid 1.2.6 2021-04-19 12:57:21 +08:00
agapple
a09cd9adb5 fixed issue #3110 , json escapse 2021-04-19 11:28:45 +08:00
agapple
1369418c6a fixed code format & merge 2021-04-19 10:55:43 +08:00
995586041
75174a63af 增加rabbitmq消息持久化deliveryMode配置 (#3300) 2021-04-19 10:29:23 +08:00
zoemak
17f4ee13e7 自动注册时可自定义node server名称,canal.properties#canal.admin.register.name,为空则使用canal.register.ip (#3459) 2021-04-19 10:18:01 +08:00
Fei Yang
f0417502f8 fix: unit_present typo (#3461)
https://github.com/alibaba/canal/issues/3434
2021-04-19 10:16:17 +08:00
renyansongno1
a7720b51e4 支持rocketmq的消息按照tag去发送 (#3438)
* 支持rocketmq的消息按照tag去发送
并对应修改了配置文件

* 将tag的设计转移到Rocketmq的单独配置项
2021-04-19 10:14:27 +08:00
suman-lee
21904ef1dc 基于明确的I/U/D是否过滤 (#3452)
* dmls filter

* dmls filters

* 基于明确的I/U/D是否过滤

* 基于明确的I/U/D是否过滤
2021-04-19 10:10:54 +08:00
agapple
94425223bd fixed issue #3454 , concurrent env bugfix 2021-04-17 10:57:25 +08:00
agapple
7857df9701 add sql parser testcase 2021-04-17 10:49:17 +08:00
agapple
64ea4ff222 fixed issue #3267 , fixed rockemq send null message 2021-04-17 10:25:49 +08:00
agapple
85df89f777 fixed issue #3377 , escapse schema name 2021-04-16 23:11:41 +08:00
AlphaKitty
a0f8e182ec 修复当host中存在冒号(比如https:)抛UnknownHostException问题 (#3223)
* 修复当host中存在冒号(比如https:)抛UnknownHostException问题

* 更优雅地解析url
2021-04-16 22:11:21 +08:00
温绍锦
33721d0394 update druid version (#3146)
* replace fastsql with druid

* update druid version
2021-04-16 22:09:40 +08:00
Treeyh
91bddfeed6 修复接入阿里云RocketMq no route info for this topic 问题 (#3220)
Co-authored-by: hai.yu <hai.yu@snowballtech.com>
2021-04-16 22:08:28 +08:00
16075140
25feab4af8 support rabbitmq port by config (#3236) 2021-04-16 22:07:12 +08:00
binbin
f66baeabf1 修复最近位置被remove掉,导致重复消息的问题 (#3276) 2021-04-16 22:03:51 +08:00
agapple
b1dc3821ea fixed config url auth 2021-04-16 21:52:23 +08:00
Jump-Boy
f5f79104eb fix centos 6.10 yum bug and update jdk8.rpm download url (#3398) 2021-04-16 21:41:55 +08:00
ltamber
e8d138d3bd fix: uuidset combine fix (#3432) 2021-04-16 21:37:55 +08:00
zoemak
32d9e58915 升级rocketmq到4.8.0,并且支持环境变量优先配置 (#3450) 2021-04-16 21:35:11 +08:00
许道杰
58448e559d fix: issue #2649 client-adapter启动时抛LinkageError异常、#3073 client-adapter通过启动参数传入canal.tcp.zookeeper.hosts为空值时抛异常 (#3074) 2021-04-16 21:25:14 +08:00
许道杰
fede3b3d1d fix #3126 将hbase-client依赖修改为hbase-shaded-client (#3127) 2021-04-16 21:24:44 +08:00
许道杰
5d8ec31bc4 fix #3119 (#3121) 2021-04-16 21:22:31 +08:00
WangCong
82b18ebe62 feat unsigned bug (#3104) 2021-04-16 21:17:43 +08:00
hupeng
66408782b0 process()方法中,在retry循环中处理成功应该break (#3080)
process()方法中,在retry循环中处理成功应该break
2021-04-16 21:14:43 +08:00
许道杰
846c8870ae fix: issue #3076 (#3077) 2021-04-16 21:12:12 +08:00
ljcoder
8cfb07f07e 数据库名称如何存在中划线"-"情况下,SQL执行异常 (#3228)
Co-authored-by: liguowang <liguowang@aerozhonghaun.com>
2020-12-31 11:33:01 +08:00
文哥
d741425895 升级guava 至 22.0 (#3184)
* fix issue:#561 增加一个外部参数控制,允许位点不存在时自动重置到当前位点

* Add MariaDB GTID support

* remove client pom bad ns

* upgrade guava version to 22.0
2020-11-20 13:47:26 +08:00
文哥
20add85ff6 统一Canal 依赖的Spring 版本,升级ibatis 至mybatis (#3182)
* fix issue:#561 增加一个外部参数控制,允许位点不存在时自动重置到当前位点

* Add MariaDB GTID support

* 1. fix maven central repository url access error.(Update to https)
2. upgrade spring version to 5.0.5.RELEASE
3. upgrade ibatis to mybatis

* fix unit test run error
2020-11-20 09:24:56 +08:00
agapple
a5c09c521e Update README.md 2020-11-02 12:54:54 +08:00
agapple
c94276b1ac Update README.md 2020-11-02 12:53:35 +08:00
agapple
272d575c78 Update README.md 2020-11-02 12:44:59 +08:00
温绍锦
693f8d501a replace fastsql with druid (#3132) 2020-10-31 13:19:03 +08:00
温绍锦
bb1b6b9862 Update README.md 2020-10-23 14:41:31 +08:00
温绍锦
8ed82caaef Update README.md 2020-09-29 16:18:23 +08:00
文哥
de1dd70609 1. Add MariaDB gtid support 2. fix issue:#561 增加一个外部参数控制,允许位点不存在时自动重置到当前位点 (#3025)
* fix issue:#561 增加一个外部参数控制,允许位点不存在时自动重置到当前位点

* Add MariaDB GTID support
2020-09-24 17:56:40 +08:00
zavakid
09429c241f = inner class MessageEventFactory to be static 2020-09-23 11:37:17 +08:00
zavakid
9a332940d7 = remove unused import 2020-09-23 11:34:45 +08:00
zavakid
362974b1c2 = code cleanup: remove unnessary boxing 2020-09-18 00:54:23 +08:00
zavakid
435db30b7b = performance improve
- using bulk operation instead of iteration if possible
  - terminate loop after condition is met
2020-09-18 00:51:53 +08:00
zavakid
e7de8289cd = code cleanup : modified inner class to 'static' if possible 2020-09-18 00:49:48 +08:00
zavakid
5065fea963 = fix BooleanMutex's inner Sync to static class and add test case 2020-09-18 00:44:25 +08:00
zavakid
6989eb3d2b + fix logging call placeholders number 2020-09-17 23:26:02 +08:00
zavakid
df24596092 = code cleanup
- for loop replaceable with enhanced 'for' loop
  - using diamond in generic type
  - collapse try catch exception
  - using try-with-resource
  - using  List#sort instead of Collections#sort
  - replaced lambda with method reference
  - using native compare method to compare numbers
  - using switch instead of if for in ESSyncUtil
2020-09-17 23:22:25 +08:00
zavakid
43c23ffb97 = remove unused improt 2020-09-17 22:40:06 +08:00
zavakid
e7658879bc = cold cleanup
* using lambda if possible (we are already building in Java8)
  * using diamond when new generic instance
  * remove used improt
2020-09-17 17:46:20 +08:00
zavakid
df60eda679 = code cleanup 2020-09-16 14:18:05 +08:00
liguangyao
b81e9dfeb8 支持不同topic指定专属partitionNum (#2479) 2020-08-22 13:11:53 +08:00
agapple
b79af46054 merge code and fixed issue #2755 #2756 #2735 #2714 #2711 #2710 #2616 #2602 #2585 #2565 #2935 #2434 #2623 #2418 #2387 2020-08-22 13:07:24 +08:00
calvinhkf
90bf9e6de5 align h2 version to 1.4.196 (#2663) 2020-08-20 21:19:22 +08:00
zhaohua
182163c3bd MemoryTableMeta ddl 处理注释2 (#2694)
* MemoryTableMeta ddl 处理注释

* MemoryTableMeta ddl 处理注释2
2020-08-20 21:19:08 +08:00
dengliming
e4726972de refactor: delete duplicate code (#2748) 2020-08-20 21:18:51 +08:00
dengliming
985892cf7e Remove deprecated sudo setting. (#2749) 2020-08-20 21:18:37 +08:00
chank
746d51e621 Change maven repository to HTTPS (#2763)
* change maven repository to https

* change maven repository to https
2020-08-20 21:18:25 +08:00
caoyixiong
cdd077b758 FIX NPE When ddl event (#2801) 2020-08-20 21:18:12 +08:00
DinoZhang
72ae7ba8d7 meta admin (#2836) 2020-08-20 21:18:00 +08:00
Tocker
b82c8bca83 Fix:Alibaba Coding Guidelines-Object的equals方法容易抛空指针异常,应使用常量或确定有值的对象来调用equals。 (#2919) 2020-08-20 21:17:44 +08:00
Tocker
576406a4ce Fix:Alibaba Coding Guidelines-所有的包装类对象之间值的比较,全部使用equals方法比较 (#2918) 2020-08-20 21:17:32 +08:00
Ymangz
b5b08e92e3 Unbuntu 20.0 默认sh为dash执行时会报语法异常 (#2939) 2020-08-20 21:17:11 +08:00
wanshao
9f6021cf36 fix(dml): revert wrong fix 2020-03-13 17:41:53 +08:00
bucketli
0e3d719a39 refact(canal):duplicate dependence 2020-03-09 14:15:40 +08:00
agapple
afbf125231 fixed format 2020-03-05 15:26:59 +08:00
agapple
b2b2a82554 client-adapter 写入kudu (#2396)
* client-adapter 提交写入kudu适配器

* kudu etl 处理数据缓存提交问题

* Update KuduTemplate.java

* 1.写入kudu前获取元数据方式更改
2.解决etl批量导入kudu数据少量丢失问题

* 1.修改文件头注释
2.调整kudu更新事件update为upsert
2020-03-05 15:22:01 +08:00
wanshao
30a1b067a8 fix(project): no need to process tinyint(1) specially #631 2020-02-28 14:34:30 +08:00
wanshao
beaca165d0 Merge branch 'master' of github.com:alibaba/canal 2020-02-28 14:24:33 +08:00
wanshao
c21c18458b fix(project): fix isDdl judge #2599 2020-02-28 14:21:12 +08:00
agapple
5e761e14fa format 2020-02-28 13:15:27 +08:00
agapple
18418ebd98 merge pull/2120 2020-02-28 12:29:41 +08:00
844392610
92f04f86cb 添加目标表不区分大小写的支持,并可开关(默认为区分大小写) (#2329)
* 添加目标表不区分大小写的支持,并可开关(默认为区分大小写)

* 添加目标表不区分大小写的支持,并可开关(默认为区分大小写)-format
2020-02-28 12:22:17 +08:00
littleneko
0d5505aa2c fix_json_type_opaque_parse_err (#2318)
对于`JSONB_TYPE_OPAQUE`类型的解析计算`q_max_bytes`时,多算了`1`字节
2020-02-28 12:15:09 +08:00
zhshy11
bd56438eca sql语句增加引号,兼容mysql关键字 (#2358) 2020-02-28 11:47:38 +08:00
agapple
b9a157657f merge /pull/2373 2020-02-28 11:46:28 +08:00
agapple
523e8b85e6 format 2020-02-28 11:40:14 +08:00
agapple
ab74b2c82c fixed mq spi package 2020-02-28 11:32:30 +08:00
rewerma
265a8e8594 模块化mq connector (#2562)
* add connector module, add kafka producer connector module for server

* add rocketMQ producer connector module for server

* add rabbitMQ producer connector module for server

* optimize code, add annotation

* add canal message consumer connector for canal-adapter module
2020-02-28 11:00:08 +08:00
jianqingdu
4fc7e5f7d9 fix bug: wrong quit command implementation (#2554) 2020-02-28 10:52:35 +08:00
Li Qiang
9cc8caa834 feature(canal):support start with timestamp position(empty journal_file,set position=0),#2594 (#2595) 2020-02-28 10:50:38 +08:00
Li Qiang
a71375dad5 fix(canal):fix endless local binlog mode with exception. (#2597) 2020-02-28 10:48:54 +08:00
Rg
70d8a379f2 add Rust canal client support (#2518) 2020-01-15 20:12:28 +08:00
rewerma
b6333f018f Revert "修复kafka消费回滚的bug (#2521)" (#2526)
This reverts commit 31acfc0101.
2020-01-02 17:04:57 +08:00
rewerma
31acfc0101 修复kafka消费回滚的bug (#2521) 2020-01-02 16:15:47 +08:00
rewerma
6d9ea57186 修复子线程阻塞造成不能中止的问题 (#2508) 2019-12-26 19:29:48 +08:00
Li Qiang
c4c0255073 Update README.md 2019-11-04 10:20:00 +08:00
agapple
1fa9020599 format 2019-10-15 21:38:48 +08:00
agapple
dd7554374f format 2019-10-15 21:35:57 +08:00
shicongyang
65b5325ca6 建议增加一个属性,针对根据某一字段hash时,hash算法可以不根据database算出 #2248 (#2294) 2019-10-15 21:32:42 +08:00
agapple
b64a3e301a fixed issue #2286 , ArithmeticException zero 2019-10-10 15:37:17 +08:00
agapple
31562919bb rename canal-admin project to admin 2019-10-09 14:50:08 +08:00
agapple
9c75e25da7 optimizer pom dependency 2019-10-09 14:18:37 +08:00
agapple
7d91850be6 fixed issue #2257 , time 100 parse bugfix 2019-10-09 13:39:22 +08:00
agapple
4af3b24b69 fixed issue #2281 , null reject 2019-10-08 18:50:37 +08:00
craigwu9
e4e66b143c make canal.admin.port canal.admin.user canal.admin.passwd can be override by system env properties (#2274)
* Update SimpleAdminConnectors.java

add more information about which server execute failed

* Update CanalStarter.java

make canal.admin.port canal.admin.user canal.admin.passwd can be override by system env
2019-09-30 20:45:00 +08:00
agapple
dd93e2b0c4 fixed issue #2258 , optimizer rabbitmq send perf & matchTopics only match one Topic 2019-09-30 20:42:52 +08:00
agapple
d505b5ab9d fixed issue #2258 , optimizer rocketmq send perf 2019-09-30 20:19:25 +08:00
agapple
0fb717a97f fixed issue #2258 , optimizer kafka send perf 2019-09-30 14:24:59 +08:00
一杯Hash
c634f98fca bugfix mysql >= 8.0, 缓存层移除,EbeanServer 运行 Fail,Unknown system variable query_cache_size error! (#2264)
threw exception; nested exception is javax.persistence.PersistenceException: java.sql.SQLException: Unknown system variable 'query_cache_size'
2019-09-29 10:51:17 +08:00
rewerma
460479390a bug fix (#2249) 2019-09-26 10:58:28 +08:00
Li Qiang
26013e239d Update README.md 2019-09-25 19:49:22 +08:00
agapple
46fe40ed47 use es6x/es7x instead of elaticsearch project 2019-09-25 19:31:52 +08:00
Koshoooooo
0c27bcf73e Fix issue #2221 (#2242)
fastjson修复了拒绝服务安全问题,升级到当前1.2.58的兼容安全版本1.2.58.sec06
2019-09-25 19:28:13 +08:00
agapple
d86b0e6e67 fixed testcase 2019-09-25 19:16:33 +08:00
EdgarScott
fff623acb1 Add unit tests (#2235)
* Add Unit Tests for the following classes:

com.alibaba.otter.canal.client.adapter.support.JdbcTypeUtilTest
com.alibaba.otter.canal.client.adapter.support.UtilTest
com.taobao.tddl.dbsync.binlog.JsonConversion_Json_ValueTest
com.taobao.tddl.dbsync.binlog.JsonDiffConversionTest
com.taobao.tddl.dbsync.binlog.LogBufferTest
com.taobao.tddl.dbsync.binlog.LogEventTest
com.taobao.tddl.dbsync.binlog.event.LogHeaderTest
com.taobao.tddl.dbsync.binlog.event.RowsLogBufferTest
com.alibaba.otter.canal.parse.driver.mysql.packets.client.RegisterSlaveCommandPacketTest
com.alibaba.otter.canal.parse.driver.mysql.utils.ByteHelperTest
com.alibaba.otter.canal.parse.inbound.mysql.ddl.DdlResultTest
com.alibaba.otter.canal.parse.inbound.mysql.ddl.DruidDdlParserTest

These tests were written using Diffblue Cover

* Add dependencies and refactor
2019-09-25 18:53:24 +08:00
rewerma
f45c0206da Add elasticsearch 7.x version adapter support (#2246)
* init es data sync upgrade

* Add elasticsearch 7.x version adapter support
2019-09-25 18:51:34 +08:00
gaecfov
61726c7e05 fix: ES配置文件监控问题 (#2202)
* fix:
ES监控配置文件时如果第一次因为文件错误新增失败后,再次修改不会新增的问题
ES监控配置文件添加的Config缓存没有带Instance导致匹配不到的问题

* fix:ES配置文件监控不生效
2019-09-17 09:22:55 +08:00
耐小心
79552e0a37 rabbitmq(amqp)MQ支持 (#2156) 2019-09-16 12:43:02 +08:00
agapple
5ec2087257 fixed issue #2197 , startup.bat fix 2019-09-16 09:58:27 +08:00
rewerma
5214257cd4 ES子表含group的where条件拼接 (#2190)
* ES子表含group的where条件拼接

* modify
2019-09-16 09:47:02 +08:00
gaecfov
365ca4d01f fix:当查询列包含常量拼接时解析主键字段进行条件拼接时会多出 where null=null (#2188) 2019-09-16 09:44:59 +08:00
agapple
419a73b3de fixed issue #2168, ignore create database 2019-09-12 09:08:30 +08:00
Jony
c093fbb8f6 动态刷新同步锁状态 (#2181)
* 解决修改数据库远程配置,canal-adapter 一直循环destroy、init。

* 解决动态添加instance和对应的adapter无锁状态问题。
2019-09-12 08:52:33 +08:00
rewerma
31bb85bea3 fix bug #2023 and code optimize (#2167)
* 减少等待刷新状态时间

* fix bug #2023
2019-09-12 08:47:22 +08:00
rewerma
803565456f fix modified_time null value error (#2157)
* template config load

* compile vue frontend for product

* fix modified_time null value error

* modify
2019-09-07 21:53:11 +08:00
Li Qiang
520f5771d8 Update README.md 2019-09-06 15:02:34 +08:00
Li Qiang
5fbd6f6606 Update README.md 2019-09-06 14:57:47 +08:00
Li Qiang
bc9c7f0f1d Update README.md 2019-09-06 14:54:22 +08:00
Li Qiang
08a2f0aa44 Update README.md 2019-09-06 14:45:33 +08:00
Li Qiang
a0387faa67 Update README.md 2019-09-06 14:45:14 +08:00
Li Qiang
1dd4674ccb Update README.md 2019-09-06 13:36:04 +08:00
Jony
60e26d1ddd 解决修改数据库远程配置,canal-adapter 一直循环destroy、init。 (#2137) 2019-09-04 12:25:54 +08:00
agapple
ecdab76705 fixed issue #2129 , Negative seek offset 2019-09-03 08:51:21 +08:00
agapple
403fdf997c Update README.md 2019-09-02 19:28:49 +08:00
agapple
a9e83463e0 Update README.md 2019-09-02 19:27:50 +08:00
agapple
2bde4327c7 [maven-release-plugin] prepare for next development iteration 2019-09-02 14:24:16 +08:00
agapple
d53bfd7ee7 [maven-release-plugin] prepare release canal-1.1.4 2019-09-02 14:24:03 +08:00
agapple
ccc45b672c fixed issue #2127 , remove logback stdout 2019-09-02 14:10:29 +08:00
agapple
0d42bdafe2 fixed stdout 2019-09-02 14:04:19 +08:00
agapple
95050ff382 fixed test example 2019-09-02 13:46:35 +08:00
agapple
5addd246ac fixed unused error 2019-09-01 11:20:00 +08:00
agapple
cfc95e2b7a fixed docker config 2019-09-01 10:41:00 +08:00
agapple
44187d9e3a fixed docker config 2019-09-01 10:15:58 +08:00
agapple
c76e8ba0e4 fixed canal-admin 2019-08-31 15:23:58 +08:00
rewerma
1bcae9dc49 template config load (#2123)
* template config load

* compile vue frontend for product
2019-08-31 14:56:28 +08:00
agapple
3a388308d9 fixed compiler error 2019-08-31 13:01:52 +08:00
agapple
a60ec6fa42 fixed tescase failed 2019-08-31 13:00:31 +08:00
agapple
456945fe3a add autoRegister and cluster 2019-08-31 12:59:12 +08:00
agapple
ba24c15833 add conflict file 2019-08-31 12:47:27 +08:00
agapple
4e0b8a0278 fixed admin 2019-08-31 12:24:41 +08:00
rewerma
274e91f8aa bug fix (#2122)
* admin端口调整完成

* server端适配调整

* 调整部分功能

* 单机/集群admin调试完成

* 重新发布前端页面

* bug fix

* 解决server端admin配置会被远程覆盖的问题
解决default-instance.xml无法加载远程zkServers配置的问题

* 集群模式下取活动实例的问题
2019-08-31 12:22:16 +08:00
rewerma
89055f7405 canal-admin完善 (#2121)
* admin端口调整完成

* server端适配调整

* 调整部分功能

* 单机/集群admin调试完成

* 重新发布前端页面
2019-08-30 18:09:22 +08:00
rewerma
e8dba41216 code optimize (#2108)
* code optimize
2019-08-27 22:52:14 +08:00
agapple
f52b2cccd5 fixed testcase 2019-08-27 22:45:27 +08:00
rewerma
7386327af9 code optimize (#2107)
* admin assembly打包

* 修改npm  profile

* code optimize

* code optimize
2019-08-27 22:24:53 +08:00
rewerma
c48407b449 修改npm profile (#2106)
* admin assembly打包

* 修改npm  profile
2019-08-27 20:55:15 +08:00
rewerma
d92badeb45 admin assembly打包 (#2104) 2019-08-27 19:48:22 +08:00
agapple
7093179cc8 fixed issue #2099 , rename poll to polling 2019-08-27 16:25:42 +08:00
agapple
bf89974f7c fixed issue #2099 , support remote config poll 2019-08-27 16:11:20 +08:00
rewerma
2e1b7a5093 通过http从canal-admin中拉配置 (#2093)
* modify

* http拉取配置监听

* revert main pom

* 整理代码
2019-08-26 19:01:08 +08:00
agapple
3d4dbc9a8c fixed issue #2099 , support user/passwd acl and canal admin operator 2019-08-26 18:16:33 +08:00
agapple
e376a129ed fixed canal-admin vue 2019-08-24 16:54:27 +08:00
wangwengeek
983ff5fc73 查询数据过长变成byte数组转化为json解决 (#2090)
Caused by: com.alibaba.fastjson.JSONException: syntax error, pos 2, json : [B@406b7f2 #2089
2019-08-23 17:38:22 +08:00
agapple
3a74f6124a fixed issue #1940 #2088 , add canal.register.ip support docker 2019-08-22 23:48:19 +08:00
agapple
bd974e3da8 upgrade fastjson 1.2.58 2019-08-22 23:03:22 +08:00
agapple
86cd805a64 upgrade fastsql 973 2019-08-22 22:02:58 +08:00
agapple
8b54b9e596 add python client info 2019-08-22 15:17:33 +08:00
agapple
2d3baeab7d fastsql tsdb testcase 2019-08-22 15:08:36 +08:00
黄大海
7b245c5a64 fix #1762 (#1959) 2019-08-21 14:33:31 +08:00
agapple
78af6b1130 fixed issue #2067 , add example 2019-08-21 13:52:34 +08:00
ever
7547cac3c5 fix compiler problem: upgrade rocketmq to 4.5.2 (#2074) 2019-08-21 12:48:46 +08:00
soocold
066743cfd6 always check whether ringbuffer has an exception in event processor (#2053) 2019-08-21 12:46:17 +08:00
rewerma
fdd0763567 新增es adapter rest client和认证机制 (#2046)
* 新增es adapter rest client和认证机制

* 修改getMapping位置

* 代码调整

* 代码调整

* 整理代码

* fix #2048
2019-08-21 12:44:57 +08:00
ThomasPerkins1123
bcdbf75dc5 Add unit tests for com.alibaba.otter.canal.parse.driver.mysql.utils.ByteHelper (#2039)
These tests were written using Diffblue Cover.
2019-08-21 12:44:24 +08:00
jason-liew
db23f15b61 fix: hbase etl sql syntax error in some case (#2034) 2019-08-21 12:44:04 +08:00
rewerma
44722fe01c canal-admin-ui 指定profile编译 (#2019)
* canal-admin-ui 指定profile编译

* 启动实例时选择指定节点

* modify

* modify

* 静态页面修改
2019-07-22 09:15:14 +08:00
bucketli
be9813142f remove openjdk12 2019-07-20 19:05:49 +08:00
bucketli
c48e80a163 remove oraclejdk8 CI config,add oraclejdk12 and openjdk12 2019-07-20 18:34:01 +08:00
bucketli
c1bfad4f2d 1.not compile canal-admin module,unless you need it, to be optimize.#1998,2.support JDK 11 & 12 ,3.fix the CI block test 2019-07-20 18:12:07 +08:00
rewerma
10f4ef6acd canal admin (#1998)
* 增加注解

* modify

* 文件大小写问题
2019-07-16 21:47:53 +08:00
Li Qiang
4c0d82fb98 Update README.md 2019-07-16 20:35:37 +08:00
rewerma
7cec0994e9 Merge branch 'master' into master 2019-07-14 19:24:42 +08:00
mcy
483044916d canal admin 2019-07-14 19:18:15 +08:00
mcy
c8bb6e200c modify 2019-07-14 09:59:58 +08:00
mcy
9cc6b67426 ddl sql 2019-07-14 09:59:35 +08:00
mcy
62072ea9ab modify 2019-07-14 00:06:25 +08:00
mcy
f3daceea6b canal instance manager module finished 2019-07-13 21:34:44 +08:00
rewerma
4efc0f6078 modify 2019-07-13 18:03:28 +08:00
rewerma
40d2a8c6cc modify 2019-07-13 14:33:42 +08:00
rewerma
28da536ec8 modify 2019-07-13 11:47:55 +08:00
mcy
6f129bf524 modify 2019-07-12 21:00:33 +08:00
mcy
31ae308760 增减jmx状态控制 2019-07-12 20:59:20 +08:00
mcy
c2ce662f9a modify 2019-07-12 20:08:16 +08:00
mcy
7044e172f5 jmx 客户端 2019-07-12 20:06:58 +08:00
Menng
c070757da0 修正文档链接&优化格式 #1965 (#1967) 2019-07-12 10:13:29 +08:00
xingwenge
92dd2bb189 Update README.md (#1981) 2019-07-12 09:53:06 +08:00
rewerma
8639b45fe9 fix #1761 (#1973)
* Message转Dml对null值的判断

* Message转Dml对null值的判断

* Message转Dml对null值的判断

* fix #1761
2019-07-12 09:52:36 +08:00
mcy
6b9487a0a0 modify 2019-07-12 09:16:10 +08:00
rewerma
5741f5a347 modify 2019-07-12 00:42:18 +08:00
rewerma
4c3ef6772c modify 2019-07-12 00:01:37 +08:00
rewerma
64824bc5aa modify 2019-07-11 23:29:49 +08:00
mcy
23209f24ed 增减jmx状态控制 2019-07-11 21:34:12 +08:00
mcy
015026ea91 modify 2019-07-11 21:31:38 +08:00
mcy
c7967e989c modify 2019-07-11 20:46:02 +08:00
mcy
e4b37f33de modify 2019-07-11 20:44:39 +08:00
mcy
598f15a404 modify 2019-07-11 16:30:50 +08:00
mcy
ec5f1eb10d modify 2019-07-11 16:16:32 +08:00
mcy
28c0aac98d modify 2019-07-11 15:11:29 +08:00
mcy
50ea6870dc modify 2019-07-11 15:07:57 +08:00
mcy
317439670c modify 2019-07-11 10:16:12 +08:00
rewerma
64ff140304 modify 2019-07-11 01:05:11 +08:00
rewerma
a93af74539 modify 2019-07-11 00:20:56 +08:00
rewerma
fc39b2af68 modify 2019-07-10 21:46:38 +08:00
mcy
e87a0c3b63 canal-admin init 2019-07-10 16:22:38 +08:00
mcy
b43043f4e4 Merge remote-tracking branch 'origin/master' 2019-07-09 19:09:24 +08:00
mcy
60a46ae941 fix #1761 2019-07-09 19:08:35 +08:00
Braavos
b5c05c2fd2 Add unit tests for com.alibaba.otter.canal.parse.driver.mysql.utils.MySQLPasswordEncrypter (#1937)
These tests were written using Diffblue Cover.
2019-06-28 14:57:18 +08:00
靳光宇
0cf18976d9 Update HbaseSyncService.java (#1936)
Fix batch update or delete with only affects the first data issue
2019-06-28 14:56:51 +08:00
Li Qiang
803c0607d3 Update README.md 2019-06-27 19:45:26 +08:00
Li Qiang
f04e742f4f #1897 , fix DummyEventStore implements new method (#1932) 2019-06-27 09:58:24 +08:00
cjk87927
c81034dda3 增加表字段过滤功能 (#1914)
* 增加表字段过滤功能

* 增加表字段过滤功能

* 更换fastsql版本通过编译

* 1.修改字段配置格式 2.增加字段黑名单配置(冲突时以白名单为准)
2019-06-26 17:45:14 +08:00
agapple
a847660a45 fixed issue #1826 , remove kafka transaction send 2019-06-26 16:02:19 +08:00
agapple
4957083493 fixed issue #1897 , memory event store ack null 2019-06-25 17:32:46 +08:00
rewerma
24f0eece42 Merge pull request #1 from alibaba/master
merge
2019-06-19 21:00:31 +08:00
agapple
adccc0e912 add logger info for query_log_event 2019-06-19 15:04:22 +08:00
agapple
8728beb4b6 fixed compile 2019-06-18 22:18:30 +08:00
agapple
5bea876ec9 fixed issue #1352, add pkNames for flatMessage partition 2019-06-18 21:44:52 +08:00
agapple
6c494f8892 add rocketmq-client pom version 2019-06-18 21:28:55 +08:00
BillowX
74489d1bba 当MQ配置为Kafka时,支持配置Kerberos认证 (#1895) 2019-06-18 15:02:14 +08:00
Z6N
5ac0f7b710 按主键散列,未设置主键时无限空指针异常 (#1889)
当按注解散列时,如果监控的表未显示设置主键,将会导致flatMessage.getPkNames()为空,导致无限空指针异常
2019-06-18 15:01:00 +08:00
lanxinxu
75b4911caf 线程安全的获取meta (#1866) 2019-06-18 14:59:30 +08:00
lanxinxu
95602f4784 并行解析模式下有丢数据风险 (#1857) 2019-06-18 14:57:59 +08:00
agapple
058e1fc546 fixed delete message send mq bugfix 2019-05-28 00:14:20 +08:00
lulu2panpan
e808c6ec70 AbstractCanalInstance的subscribeChange方法,增加对AbstractEventParser的类型判断;MysqlEventParser对Gtid的处理需要考虑兼容性 (#1824)
* AbstractCanalInstance的subscribeChange方法,增加对AbstractEventParser的类型判断,以支持用户的自定义CanalEventParser

* MysqlEventParser对Gtid模式的处理需要考虑兼容性,支持系统平滑的从非gtid模式升级为gtid模式
2019-05-28 00:05:13 +08:00
rewerma
ce7948d6e7 fix Message转Dml对null值的bug (#1808)
* Message转Dml对null值的判断

* Message转Dml对null值的判断

* Message转Dml对null值的判断
2019-05-28 00:03:55 +08:00
soso
8df6d6fed8 Fix: 主备切换后没有往Kafka发送数据 (#1810)
发生主备切换时,调用canalMQStarter启停对应的destination。
2019-05-28 00:03:28 +08:00
nieyuan1991
f9989e0856 fix:未捕获kafka事务异常,造成canal ack异常 (#1814) 2019-05-28 00:02:25 +08:00
xiayuan
4075a0623f set the validationQuery while testWhileIdle is true (#1827) 2019-05-27 23:56:25 +08:00
Marsss___
37fc248ebf 删除操作计算hash值的情况没有考虑,导致删除时的分区和插入时的分区不一致 (#1848) 2019-05-27 23:54:25 +08:00
Heng Du
d0a83aad27 Support seamless docking with Alibaba Cloud RocketMQ commercial service (#1849) 2019-05-27 23:51:32 +08:00
agapple
3b9ff26d1a add logo 2019-05-15 10:20:08 +08:00
mcy
4f7842c843 Message转Dml对null值的判断 2019-05-14 17:38:01 +08:00
mcy
b870e7ecd0 Message转Dml对null值的判断 2019-05-14 17:35:34 +08:00
mcy
331dd63c5f Message转Dml对null值的判断 2019-05-14 17:31:51 +08:00
JKTerrific
72c4daba5f 1:添加对于查询结果中,MAX( CASE a.key WHEN 'WORD1' THEN a.value ELSE 0 END ) AS… (#1794)
* 1:添加对于查询结果中,MAX( CASE a.key WHEN 'WORD1' THEN a.value ELSE 0 END ) AS WORD1 的竖表转横表的支持
2:添加对于查询条件尾部,使用GROUP BY _id 等分组语句时出现的sql解析异常问题

* fix index out of range
2019-05-11 17:33:59 +08:00
Jet
7427a74612 improve es etl (#1758)
* fix typo in trace log

* improve es etl

* improve es etl log

* improve es etl by add threadCount

* improve es etl by add threadCount

* improve es etl query

* remove comment
2019-05-11 17:26:08 +08:00
paascloud
24fae6fa52 变量定义错误 (#1776)
* 变量定义错误

* 变量定义错误
2019-05-11 17:21:21 +08:00
Sweet
4c690fb5a3 Null point Exception during loading the checksum (#1788)
If you connect to the mysql with version 5.1, the result of command 'select @master_binlog_checksum' is an array with only one Null element .
2019-05-11 17:17:54 +08:00
Jet
8f088cddc0 Fix es bulk (#1743)
thanks
2019-04-25 09:36:09 +08:00
Jet
e94ee64316 fix typo in trace log (#1738) 2019-04-24 09:57:05 +08:00
dataccs
3165cb9640 支持用户自定义的CanalAlarmHandler (#1736)
* 支持用户自定义的CanalAlarmHandler

* RowsLogEvent增加对TableMapLogEvent判空检查,防止NPE异常
2019-04-24 09:56:32 +08:00
rewerma
2b738f4e04 fix bugs (#1712)
* kafka 模式默认开启事务异步发送

* fix adapter etl rest sql inject bug

* fix #1704
2019-04-18 20:33:15 +08:00
rewerma
16f335c381 修复rest etl 存在SQL注入风险 (#1685)
* kafka 模式默认开启事务异步发送

* fix adapter etl rest sql inject bug
2019-04-15 23:58:12 +08:00
王超
a8bf2b641f String.split(String regex) bug fix (#1696) 2019-04-15 23:55:03 +08:00
chenxyz707
67faf0e03e resovle config/metrics as a destination folder (#1678) 2019-04-09 21:05:42 +08:00
Xin Wang
8cb85753bb open the switch to get codecov test coverage (#1671)
* add codecov for test coverage
2019-04-09 19:11:48 +08:00
agapple
df86f94409 fixed issue template 2019-04-09 15:12:30 +08:00
agapple
80594444f7 fixed issue template 2019-04-09 15:11:14 +08:00
agapple
d8996432b9 add issue template 2019-04-09 15:08:43 +08:00
agapple
69df50fe17 fixed issue #1672 , CanalKafkaProducer send 2019-04-08 19:57:00 +08:00
agapple
c5736bd5f3 Merge pull request #1670 from lovepoem/update_compile_jdk
update jacoco lib
2019-04-08 12:28:27 +08:00
Xin Wang
55030476ee reverse jdk to 1.8 2019-04-07 19:14:46 +08:00
Xin Wang
cd007088db reverse jdk to 1.8 2019-04-07 18:52:35 +08:00
Xin Wang
1fc880f255 reverse jdk to 1.7 2019-04-07 18:45:54 +08:00
Xin Wang
8c68cf833a update jacoco lib 2019-04-07 18:38:50 +08:00
Xin Wang
0de8f4691e update jacoco lib 2019-04-07 18:25:05 +08:00
Xin Wang
5a2efbf9cb update jacoco lib 2019-04-07 18:23:53 +08:00
agapple
dfab98fce1 Merge pull request #1669 from lovepoem/add_test_coverage_and_jdk11
add test coverage and jdk11
2019-04-06 23:37:40 +08:00
Xin Wang
e5c7bbffbf update pom 2019-04-06 18:13:41 +08:00
Xin Wang
e139698f6e update pom 2019-04-06 17:50:05 +08:00
Xin Wang
2b8120b6ed update pom 2019-04-06 17:49:03 +08:00
Xin Wang
68ebb3a957 update skipTests=false 2019-04-06 17:35:16 +08:00
Xin Wang
21309cb065 resove Could not resolve dependencies for project com.alibaba.otter:client-adapter.hbase🫙1.1.4-SNAPSHOT: Could not find artifact jdk.tools:jdk.tools🫙1.7 at specified path 2019-04-06 17:23:48 +08:00
Xin Wang
386567a633 resove Could not resolve dependencies for project com.alibaba.otter:client-adapter.hbase🫙1.1.4-SNAPSHOT: Could not find artifact jdk.tools:jdk.tools🫙1.7 at specified path 2019-04-06 16:56:03 +08:00
Xin Wang
95c69bb854 add test coverage and jdk11 2019-04-06 16:45:04 +08:00
Xin Wang
6febcf1a0f add test coverage and jdk11 2019-04-06 16:42:45 +08:00
agapple
fadfe1d6ca [maven-release-plugin] prepare for next development iteration 2019-04-04 10:25:44 +08:00
agapple
a7b12c7098 [maven-release-plugin] prepare release canal-1.1.3 2019-04-04 10:25:29 +08:00
agapple
2c320e8618 Merge pull request #1661 from rewerma/master
flatMessage模式下默认canal.mq.lingerMs=100
2019-04-04 10:08:34 +08:00
machey
d76d25df6c flatMessage模式下默认canal.mq.lingerMs=100 2019-04-04 00:14:27 +08:00
agapple
b95c0d03cf fixed issue #1660 ,support mysql8.0 caching_sha2_password auth 2019-04-03 23:42:41 +08:00
agapple
08af40221f Merge pull request #1658 from rewerma/master
adapter 日志打印修改
2019-04-03 12:12:56 +08:00
rewerma
d13c1eb17c Merge branch 'master' into master 2019-04-03 11:34:10 +08:00
agapple
82ed9db8ae fixed rocketmq partition out of range 2019-04-03 11:26:31 +08:00
agapple
d3195ac973 fixed issue #1626 , support alter table id first 2019-04-03 10:58:43 +08:00
agapple
15e29d276a fixed default xml config 2019-03-28 22:05:56 +08:00
agapple
d715ff64b4 fixed packet write batch 2019-03-28 21:52:51 +08:00
agapple
f63ce4ffe6 fixed mysql auth 2019-03-28 20:45:16 +08:00
agapple
a7f9a779ad fixed issue #1640 , support schema partition 2019-03-28 17:01:36 +08:00
agapple
39aeeb8c58 Merge pull request #1641 from wangsaner/master
修改canal.mq.partitionHash散列规则,使其支持同库下的不同表hash至相同分区
2019-03-28 16:58:31 +08:00
wangsaner
9826948ebb 修改canal.mq.partitionHash散列规则,
当指明pk级做分区(schema.table:pk1^pk2)时,由table.hashCode()^column.getValue().hashCode()改为database.hashCode()^column.getValue().hashCode(),从而支持同库下不同表hash至相同分区
2019-03-28 16:01:02 +08:00
wangsaner
d6ef66a281 Merge pull request #1 from alibaba/master
merge
2019-03-28 10:37:24 +08:00
agapple
97640b717b fixed compiler 2019-03-28 10:23:33 +08:00
agapple
20e7becfe9 fixed format 2019-03-28 10:19:53 +08:00
agapple
99b34ff632 Merge pull request #1639 from wangsaner/master
fixed issue #1636
2019-03-28 10:17:42 +08:00
wangsaner
739963acd0 fixed issue #1636
非flat模式,当MQ主题为多分区时,数据拆分只取了for循环里面的最后一份数据,
导致消费端只能消费到一个分区的数据
2019-03-27 21:57:04 +08:00
agapple
0ec4699149 fixed format & support Mysql Auth Switch Protocol 2019-03-27 11:54:40 +08:00
mcy
c101ae2280 Merge branch 'master' of https://github.com/rewerma/canal 2019-03-26 11:39:41 +08:00
mcy
a137deeaff 使用统一log 2019-03-26 11:29:52 +08:00
rewerma
c5be5b7a8a Merge pull request #40 from alibaba/master
merge
2019-03-26 00:43:11 +08:00
agapple
95bed6bcf6 fixed fastsql 2019-03-25 19:50:02 +08:00
agapple
661d119265 fixed issue #1625, mq dymaic topic match 2019-03-25 17:54:35 +08:00
agapple
08167c95c7 Merge pull request #1622 from rewerma/master
fix bugs
2019-03-22 18:14:14 +08:00
mcy
37c5168a7d code optimization 2019-03-22 14:49:50 +08:00
mcy
579fa72ae2 kafka consumer connector引入事务隔离级别 fix #1512 2019-03-22 13:44:02 +08:00
rewerma
844c019433 Merge pull request #39 from alibaba/master
merge
2019-03-22 09:10:43 +08:00
agapple
c94e3a0024 fixed default properties 2019-03-21 20:59:09 +08:00
agapple
f6ca489984 Merge pull request #1620 from rewerma/master
fix bugs
2019-03-21 20:51:10 +08:00
agapple
b2b69307f9 fixed rocketmq 2019-03-21 20:50:52 +08:00
agapple
531b535228 fixed bug 2019-03-21 20:26:00 +08:00
mcy
99cccd2113 fix #1608 2019-03-21 20:07:06 +08:00
rewerma
38d8c3d462 Merge branch 'master' into master 2019-03-21 19:42:07 +08:00
agapple
024ffc2aa2 fixed mq partition num priority 2019-03-21 19:39:21 +08:00
agapple
a81d2710ff fixed MQ partition 2019-03-21 19:27:39 +08:00
mcy
4bad0e88f8 增加日志配置 fix #1570 2019-03-21 19:04:33 +08:00
mcy
0181dfaa42 sql解析对case when 的支持
fix #1598
2019-03-21 18:35:58 +08:00
rewerma
0411d99e7b Merge pull request #37 from alibaba/master
merge
2019-03-21 18:07:41 +08:00
agapple
8fcdd7f798 Merge pull request #1619 from rewerma/master
fix #1608
2019-03-21 17:58:57 +08:00
mcy
b0f4e4ee78 fix #1608 2019-03-21 17:55:35 +08:00
agapple
d448455ebf Merge pull request #1613 from KangZhiDong/master
set utf8mb4 to support emoji
2019-03-21 16:49:44 +08:00
agapple
e07fdb6426 Update README.md 2019-03-21 16:46:42 +08:00
agapple
38336b249e fixed travis 2019-03-21 16:36:41 +08:00
agapple
e7b81cd83a fixed mvn wrapper 2019-03-21 16:30:05 +08:00
agapple
2810e7e815 add mvnw 2019-03-21 16:20:13 +08:00
agapple
024986a195 fixed travlis.yml 2019-03-21 16:16:31 +08:00
kangzhidong
9b2ad0eafd set utf8mb4 to support emoji 2019-03-20 16:29:53 +08:00
康智冬
03d46f150f Merge pull request #2 from alibaba/master
update
2019-03-20 16:21:38 +08:00
agapple
b488ca02d8 fixed travlis 2019-03-20 13:55:29 +08:00
agapple
17a6ba9c9c fixed travlis 2019-03-20 13:44:29 +08:00
agapple
3b618740d4 Merge pull request #1607 from rewerma/master
ES同步新增父子文档索引适配
2019-03-20 13:35:25 +08:00
mcy
06bfcda275 code optimization 2019-03-20 10:41:51 +08:00
mcy
5821c1f606 modify 2019-03-20 09:10:15 +08:00
mcy
a2360efff9 增加对sql字段 `` 的支持
fix #1559
2019-03-19 19:13:15 +08:00
mcy
51c469aa6f es etl 主键类型bug fix #1559 2019-03-19 17:54:11 +08:00
mcy
6b3bf31404 adapter代码整理优化 2019-03-19 17:49:00 +08:00
mcy
941ed7f60d Merge branch 'feature/es2' 2019-03-18 09:06:58 +08:00
rewerma
9db2bd291b Merge pull request #36 from alibaba/master
merge
2019-03-18 09:05:47 +08:00
agapple
95b26c4d1d fixed #1433, optimzier code 2019-03-17 10:35:16 +08:00
agapple
b114e0cb15 Merge pull request #1581 from alexinea/master
CanalSharp has transferred to .NET Core Community
2019-03-17 10:30:03 +08:00
agapple
5c96bf282e Merge pull request #1590 from rewerma/master
fix #1585
2019-03-17 10:29:12 +08:00
agapple
6d280d1048 Merge pull request #1597 from KangZhiDong/master
fix the error log does not contain table name
2019-03-17 10:28:47 +08:00
agapple
cf4db1625d Merge pull request #1605 from lizhyocx/master
解决单核服务器无法订阅数据的bug
2019-03-17 10:27:50 +08:00
lizhyocx
df98fec945 解决单核服务器无法订阅数据的bug
解决单核服务器c中anal.instance.parser.parallel = true时无法订阅数据的bug
2019-03-15 17:11:14 +08:00
mcy
e03705e211 es父子文档索引ETL支持 2019-03-13 17:19:08 +08:00
mcy
4df60a0fb5 es增加父子文档索引同步适配 2019-03-13 16:57:23 +08:00
kangzhidong
078673c6a9 fix the error log does not contain table name 2019-03-13 16:55:38 +08:00
mcy
4bd91a1079 fix bug 2019-03-13 14:36:27 +08:00
mcy
05ad671cc1 es增加relations配置
配置monitor yml加载使用通用加载类
2019-03-13 14:34:31 +08:00
mcy
43045bc672 use system time zone for es datetime field formatter 2019-03-13 10:01:16 +08:00
mcy
971c9a88c2 modify 2019-03-12 17:07:33 +08:00
rewerma
7b6e482827 Merge pull request #35 from alibaba/master
merge
2019-03-12 16:58:05 +08:00
mcy
ad39559f8c fix #1585 2019-03-12 16:56:59 +08:00
AlexLEWIS
2707c12570 CanalSharp has transferred to .NET Core Community
CanalSharp has transferred to .NET Core Community(NCC) and became a member project of NCC.
2019-03-11 14:47:14 +08:00
康智冬
7dab5ac6c2 Merge pull request #1 from alibaba/master
update
2019-03-08 10:05:20 +08:00
agapple
9d4b61f083 Merge pull request #1567 from dragontree101/miss_producergroup_properties
producerGroup配置没有读取
2019-03-06 11:07:15 +08:00
dragonlong1986
a34f9ae97b Merge branch 'master' into miss_producergroup_properties 2019-03-05 17:44:35 +08:00
dragonlong1986
64ca62b986 update 2019-03-05 17:39:56 +08:00
agapple
14c1af4c80 Merge pull request #1542 from rewerma/master
fixed #1538
2019-03-04 14:13:14 +08:00
agapple
7436d9f06f Merge pull request #1550 from lee123lee123/master
Issues #1460  修改tsdb中同步数据带表情字符错误问题
2019-03-04 14:12:33 +08:00
agapple
c4599df1c2 Merge pull request #1560 from dragontree101/doc_mistake_key
key改成大写,小写不会生效
2019-03-04 14:07:22 +08:00
dragonlong1986
7abf50f233 key改成大写,小写不会生效 2019-03-02 10:25:19 +08:00
machey
1781381187 modify 2019-03-01 00:19:47 +08:00
machey
5d4210bd22 modify 2019-02-28 23:31:07 +08:00
machey
9888fae559 负时区的bug 2019-02-28 23:22:02 +08:00
rewerma
81ab7e9783 Merge branch 'master' into master 2019-02-28 19:37:27 +08:00
mcy
b891afa50e 增加时区判断 2019-02-28 19:28:17 +08:00
lee123lee123
8187d7c5df Issues #1460 修改utf8数据带表情字符错误 2019-02-28 19:04:14 +08:00
mcy
e7f069850f fixed #1538 2019-02-28 17:29:06 +08:00
agapple
d377a92a5d fixed issue #1548, NPE 2019-02-28 10:52:28 +08:00
agapple
f664af1af4 fixed issue #1546 , support drop database 2019-02-28 10:47:42 +08:00
agapple
5e2eabb3c2 Merge pull request #1544 from finefuture/MQ-fix-pr
fix issue 1532
2019-02-28 10:32:41 +08:00
agapple
f2368e5469 Merge pull request #1540 from wurongjun/master
修复当适配器mapping文件修改时,无法生效的问题
2019-02-28 10:32:07 +08:00
TomlongTK
fd4c8db92b fix issue 1532
因为binlog日志同表名大小写的原因导致kafka的日志恢复并resize,报错之后引起集群崩溃
现在修改为投递消息的topic不区分表名大小写
2019-02-26 14:23:29 +08:00
mcy
f21abc13af fixed #1538 2019-02-26 10:23:38 +08:00
wurongjun@duiba.com.cn
ae474d67ad 修复当适配器mapping文件修改时,无法生效的问题 2019-02-25 17:53:30 +08:00
bigbro
0c4711ab62 Merge pull request #2 from alibaba/master
合并原项目最新代码
2019-02-25 17:51:19 +08:00
agapple
072420c32b fixed 2019-02-25 15:18:04 +08:00
agapple
1473a4a6b5 Merge pull request #1523 from rewerma/master
es adapter新增upsert属性
2019-02-25 14:50:58 +08:00
agapple
0fff514876 Merge pull request #1533 from DaiZZZZZ/master
CanalParameter添加parallel参数,用来配置canalinstance
2019-02-25 14:45:54 +08:00
agapple
4017de5102 Merge pull request #1526 from jiuchengspotorg/master
adapter rdb无法同步ddl更新问题修正
2019-02-25 14:15:47 +08:00
mcy
fcc1fc78ae fix #1521 2019-02-22 17:09:50 +08:00
mcy
17efc2ada0 es 批量提交修改 2019-02-22 16:56:58 +08:00
zhikuodai
a68bd28852 CanalParameter类添加parallel参数 2019-02-21 22:04:06 +08:00
daizzzzz
1de8b27da1 Merge pull request #3 from alibaba/master
merge
2019-02-21 17:25:55 +08:00
mcy
01dc8ce2b8 YmlConfigBinder代码整理 2019-02-20 15:00:48 +08:00
jiucheng
f7e490f7a0 1、adapter/rdb,从库表字段(varchar,char,text,longtext)非空约束时,无法同步问题修正
2、主库存在0000-00-00 00:00:00时间时,从库表字段是非空约束时,无法同步问题修正
2019-02-20 10:10:14 +08:00
jiucheng
8cadd585c6 adapter rdb无法同步ddl更新问题修正
adapter/support/MessageUtil.java
2019-02-20 09:49:15 +08:00
mcy
57c3226e56 Merge branch 'feature/es2' 2019-02-19 15:05:59 +08:00
rewerma
79a3961da1 Merge pull request #34 from alibaba/master
merge
2019-02-19 15:05:34 +08:00
agapple
62338a945e Merge pull request #1496 from rewerma/master
远程配置代码整理
2019-02-18 21:08:02 +08:00
agapple
e07db7b178 Merge pull request #1507 from i404/master
修复 FlatMessage  Hash 到不正确的分区的Bug。
2019-02-18 21:05:03 +08:00
mcy
05cc627b5d fix rdb etl bug 2019-02-15 11:39:26 +08:00
i404
44beaf1916 修复当 canal.mq.flatMessage = true 时,MQMessageUtils::messagePartition 数据分区错误的 bug 2019-02-14 18:26:01 +08:00
mcy
476244b26d modify 2019-02-14 15:41:27 +08:00
mcy
cfdf509f9a 增加对pk的支持 2019-02-14 15:29:27 +08:00
mcy
c14ed724ff update中增加upsert判断 2019-02-13 15:59:46 +08:00
mcy
5a4cfeab46 Merge branch 'master' into feature/es2
# Conflicts:
#	client-adapter/elasticsearch/src/main/java/com/alibaba/otter/canal/client/adapter/es/support/ESTemplate.java
2019-02-13 15:51:24 +08:00
mcy
947cf130ab fixed #1504 2019-02-13 15:50:11 +08:00
mcy
0ef21e4155 代码整理 2019-02-13 15:47:48 +08:00
mcy
83b760494d ES adapter代码重新整理
新增upsert属性
2019-02-13 15:19:09 +08:00
mcy
aba8df699c Merge branch 'master' into feature/es2
# Conflicts:
#	client-adapter/elasticsearch/src/main/java/com/alibaba/otter/canal/client/adapter/es/config/SchemaItem.java
2019-02-12 17:21:42 +08:00
rewer
0c5f5c128f 整理代码 2019-02-07 13:49:35 +08:00
mcy
ad62275cd7 增加kafka自定义properties 2019-02-05 19:20:36 +08:00
mcy
f6d03bcb37 fixed #1490 2019-02-05 17:48:08 +08:00
mcy
5284aa9793 fix bugs 2019-02-01 16:20:53 +08:00
mcy
10276e254a mq模式下adapter配置增加groupId属性对应 2019-02-01 15:18:16 +08:00
mcy
597a08ac37 通过groupId过滤对应的adapter配置 2019-02-01 13:51:49 +08:00
mcy
8211ef35e6 修改yml配置读取绑定,遵循spring yml加载方式,支持environment级占位符替换 2019-02-01 10:11:52 +08:00
mcy
a20960834b 远程配置代码整理 2019-01-31 09:45:52 +08:00
rewerma
7b6b332463 Merge pull request #33 from alibaba/master
merge
2019-01-31 09:03:37 +08:00
agapple
43f869599d Merge pull request #1484 from liulangwa/master
捕获"rs = query("select @@global.binlog_checksum")" 结果rs为null的异常
2019-01-30 11:45:33 +08:00
agapple
e3d05f6201 Merge pull request #1482 from wurongjun/master
修复从数据库加载配置写入文件时因目录不存在出现的问题
2019-01-30 11:43:47 +08:00
codebee
032301102c 捕获"rs = query("select @@global.binlog_checksum")" 结果rs为null的异常 2019-01-29 17:10:26 +08:00
wurongjun@duiba.com.cn
bb64d84298 修复从数据库加载配置写入文件时因目录不存在出现的问题 2019-01-29 16:10:26 +08:00
bigbro
ccd39e9d62 Merge pull request #1 from alibaba/master
update
2019-01-29 16:03:43 +08:00
agapple
32031da9db Merge pull request #1475 from rewerma/master
整理远程配置, 统一扩展接口
2019-01-29 10:13:03 +08:00
mcy
9a2e890f57 整理adapter端远程配置, 统一扩展接口 2019-01-25 18:50:30 +08:00
mcy
8f76b33214 解析配置修改 2019-01-25 17:51:38 +08:00
mcy
a7467539c7 整理server端远程配置, 统一扩展接口 2019-01-25 17:50:50 +08:00
agapple
db5495d158 Merge pull request #1464 from KangZhiDong/master
修改注释
2019-01-25 10:41:40 +08:00
kangzhidong
b04d948064 修改注释 2019-01-23 11:58:07 +08:00
agapple
5f8eb4d261 Merge pull request #1456 from rewerma/master
新增kafka消息投递事务
2019-01-21 23:45:13 +08:00
mcy
197ca67c8b 测试调整 2019-01-21 09:56:35 +08:00
machey
851637611f modify 2019-01-20 15:02:06 +08:00
machey
4ebf17f57b 代码调整 2019-01-20 14:30:20 +08:00
machey
2f214ce3a6 采用事务批量异步投递kafka flatMessage
fixed #1454
2019-01-20 14:20:06 +08:00
agapple
8d4fbb395b fixed issue #1451 , fixed NPE 2019-01-18 11:00:02 +08:00
agapple
d935c39648 Merge pull request #1449 from wdlily/master
fixed a word
2019-01-18 10:24:01 +08:00
wdlily
6e0e3fbef1 fixed a word
change '租' to '组'
2019-01-17 15:52:24 +08:00
rewerma
cbe88af2e3 Merge pull request #1442 from rewerma/master
fixed #1430
2019-01-17 15:18:40 +08:00
mcy
ba9d9dea6d fixed #1433 2019-01-17 11:27:12 +08:00
mcy
2d88d803ee merge #1440 and fixed #1430 2019-01-17 10:52:27 +08:00
rewerma
ff1fef1eb6 Merge pull request #32 from alibaba/master
merge
2019-01-17 10:48:23 +08:00
rewerma
4beb1e6855 Merge branch 'master' into master 2019-01-17 10:48:14 +08:00
rewerma
d2bbe9b061 Merge pull request #1440 from wurongjun/master
fix #1430
2019-01-17 10:46:30 +08:00
rewerma
171bedf488 Merge pull request #31 from alibaba/master
merge
2019-01-17 10:43:49 +08:00
mcy
e387cfdee5 fixed #1430 2019-01-17 10:22:08 +08:00
wurongjun@duiba.com.cn
47d7914304 停机时清空zk客户端信息,修复重启时报出的zk连接已关闭的异常 2019-01-16 17:28:51 +08:00
agapple
e4177ab0ce Merge pull request #1419 from rewerma/master
specified mq dynamic topic
2019-01-16 10:27:25 +08:00
mcy
739f3b4fa1 fixed #1433 2019-01-15 18:39:32 +08:00
mcy
60441d8b31 fixed #1396 2019-01-15 18:20:05 +08:00
mcy
ca41be8412 fixed #1420 2019-01-15 11:38:00 +08:00
mcy
18b304f99d specified mq dynamic topic 2019-01-14 14:25:47 +08:00
agapple
7f9dce4b77 Merge pull request #1418 from rewerma/master
fixed #1416
2019-01-14 13:10:32 +08:00
mcy
f26adff7c7 fixed #1416 2019-01-14 11:16:33 +08:00
mcy
77646c0185 拼写错误 2019-01-14 10:58:33 +08:00
agapple
7e4912cd2e Merge pull request #1413 from wingerx/master
获取TableMeta信息时,增加一次retry操作
2019-01-12 11:26:30 +08:00
agapple
70a4f0363d Merge pull request #1412 from rewerma/master
fixed #1408 fixed # 1403
2019-01-12 11:26:11 +08:00
winger
725960d46e 获取TableMeta信息时,增加一次retry操作 2019-01-11 14:00:15 +08:00
mcy
b00d347eb0 rdb adapter 增加 truncate dml适配 fixed #1408
fixed #1403
2019-01-11 13:40:37 +08:00
rewerma
92666b41e8 Merge pull request #30 from alibaba/master
merge
2019-01-11 12:59:01 +08:00
agapple
f1753e79f9 Merge pull request #1407 from lileibuaa/master
fix filter transaction entry logic in EntryEventSink
2019-01-11 10:29:06 +08:00
lileibuaa
f1a998b2d5 fix filter transaction entry logic in EntryEventSink 2019-01-10 21:16:25 +08:00
agapple
03e6662ce5 fixed mq 2019-01-08 23:57:16 +08:00
agapple
b845a67666 Merge pull request #1391 from rewerma/master
fixed 1390
2019-01-08 23:42:57 +08:00
mcy
690222bde8 dynamic topic 正则注释 2019-01-08 11:28:29 +08:00
mcy
63ad80c8c4 fixed 1390 2019-01-08 10:39:32 +08:00
agapple
de501c85a1 fixed issue #1374 , support queryLogEvent partition 2019-01-07 13:39:04 +08:00
agapple
670b7830a5 Merge pull request #1383 from rewerma/master
增加adapter远程配置
2019-01-07 13:31:01 +08:00
agapple
fdf150bd24 fixed issue #1341 2019-01-07 13:28:48 +08:00
agapple
c66b6a0f0f fixed charset 2019-01-07 12:59:33 +08:00
machey
a91aebafc2 modify 2019-01-06 21:08:17 +08:00
machey
35fcd56822 Merge branch 'feature/mgr'
# Conflicts:
#	client-adapter/rdb/src/main/java/com/alibaba/otter/canal/client/adapter/rdb/monitor/RdbConfigMonitor.java
2019-01-05 01:53:42 +08:00
machey
a63e982115 添加注释 2019-01-05 01:51:43 +08:00
machey
4bdf3d766f modify 2019-01-05 01:44:04 +08:00
machey
779ebad890 adapter 远程配置
修改rdb热加载配置的问题
2019-01-05 01:42:27 +08:00
agapple
b348260288 fixed issue #1363 , date format 2019-01-03 11:48:33 +08:00
agapple
3011c3292b Merge pull request #1362 from rewerma/master
fixed #1359
2019-01-02 22:42:22 +08:00
mcy
94b8fdbbf4 动态topic的xml配置 2019-01-02 13:28:27 +08:00
mcy
1dd9934f9c fixed #1359 2019-01-02 13:23:32 +08:00
mcy
3dec7c50ce commit 2019-01-02 11:05:46 +08:00
machey
ecd9ababa1 modify 2019-01-01 17:55:23 +08:00
machey
b0eaa156cc 增加adapter远程配置 2019-01-01 17:33:01 +08:00
agapple
a70178afef Merge pull request #1357 from rewerma/master
canal server配置统一数据库管理监控
2018-12-31 12:16:21 +08:00
machey
114c3bd020 modify 2018-12-30 17:16:47 +08:00
machey
f9e19d46c4 增加注释 2018-12-30 17:08:11 +08:00
machey
661752096c 增加注释 2018-12-30 17:04:15 +08:00
machey
100b43a5db Merge branch 'feature/mgr' 2018-12-30 16:50:32 +08:00
rewerma
5e116de264 Merge pull request #29 from alibaba/master
merge
2018-12-30 16:50:05 +08:00
machey
a1091368fb modify 2018-12-30 16:47:35 +08:00
machey
71b7c0b868 canal server增加数据库远程配置 2018-12-30 16:44:35 +08:00
mcy
7c79714528 增加远程db config配置 2018-12-29 20:21:03 +08:00
agapple
8d84521767 Merge pull request #1355 from rewerma/master
adapter 分组间线程统一抛异常
2018-12-28 23:06:08 +08:00
agapple
14ba358525 fixed dymaic topic 2018-12-28 18:35:50 +08:00
mcy
7ea1468a8d adapter 分组间线程统一抛异常 2018-12-28 17:30:04 +08:00
agapple
f72ac9a3bb fixed adapter throw exception 2018-12-28 16:55:44 +08:00
agapple
f100aeda39 Merge pull request #1345 from rewerma/master
fixed 1341
2018-12-28 15:22:20 +08:00
agapple
953a0d0583 Merge pull request #1349 from mujiansu/master
fix bat syntax error
2018-12-28 15:20:05 +08:00
agapple
2afe7debda Merge pull request #1305 from wingerx/master
修复同时开启gtid与tsdb 时gtid 属性丢失的问题
2018-12-28 15:13:47 +08:00
agapple
d8737a5228 fixed issue #1343, support charset 255 2018-12-28 13:46:50 +08:00
mcy
150a13824b 修改 kafka 异步发送 flat message 2018-12-27 17:52:33 +08:00
JasonMu
830e149d0e fix bat syntax error 2018-12-27 16:41:15 +08:00
mcy
d9e259dde4 增加支持按库名、表名动态发送topic支持 2018-12-27 15:40:04 +08:00
mcy
9e6adff942 修复adapter无法回退的问题,fixed 1341
修复HBase断连的问题
2018-12-26 15:24:30 +08:00
winger
82a78546ab Merge remote-tracking branch 'upstream/master' 2018-12-26 15:11:17 +08:00
winger
19c35c0b08 修复:当mysql 发生过purged gtid时,同时开启tsdb与gtid后,gtid属性丢失问题 2018-12-26 15:10:57 +08:00
agapple
ade2a54369 Merge pull request #1340 from rewerma/master
fixed #1338
2018-12-25 22:42:25 +08:00
machey
dffbc437a6 fixed #1338 2018-12-25 22:27:27 +08:00
mcy
b5697a366a merge 2018-12-23 18:24:04 +08:00
rewerma
0469d28c05 Merge pull request #28 from alibaba/master
merge
2018-12-23 18:20:43 +08:00
rewerma
d5f44dd76f Merge branch 'master' into master 2018-12-23 18:20:33 +08:00
mcy
354d64069f adapter增加同步异常重试 2018-12-23 18:16:47 +08:00
winger
3465866278 修复开启gtid时,同时开启tsdb后gtid 属性丢失的问题 2018-12-21 15:18:07 +08:00
agapple
840148fbf6 Merge pull request #1326 from rewerma/master
类型转换问题 fixed #1313
2018-12-21 15:10:25 +08:00
mcy
34b5f9c927 modify 2018-12-20 19:53:30 +08:00
mcy
75ee65f9e8 类型转换问题 fixed #1313 2018-12-20 19:45:57 +08:00
agapple
035ef26542 fixed issue #1306 , support MySqlOrderingExpr 2018-12-19 11:43:49 +08:00
agapple
4ef45b9a1d Merge pull request #1310 from panjianping/master
添加 KafkaOffsetCanalConnector 使用示例
2018-12-18 16:51:50 +08:00
panjianping
990fa9498a 添加 KafkaOffsetCanalConnector 使用示例 2018-12-18 16:46:19 +08:00
agapple
276a2b988a Merge pull request #1308 from panjianping/master
添加带kafka消息offset的Connector
2018-12-18 16:15:01 +08:00
panjianping
ef72cddfe8 添加带kafka消息offset的Connector 2018-12-18 11:54:41 +08:00
winger
d8d3246e30 Merge remote-tracking branch 'upstream/master' 2018-12-17 16:15:18 +08:00
winger
bba800eb96 修复开启gtid时,同时开启tsdb后gtid 属性丢失的问题 2018-12-17 16:14:55 +08:00
agapple
ff71bf515a Merge pull request #1300 from gsfeng179/master
Update README.md
2018-12-17 12:52:58 +08:00
agapple
6ef48591a1 Merge pull request #1299 from rewerma/master
FlatMessage没有默认构造方法json反序列化的问题
2018-12-17 12:52:37 +08:00
gsfeng
a7526dbf4a Update README.md
FAQ link error
2018-12-17 10:18:06 +08:00
mcy
51d94efc9c dml类整理 2018-12-17 10:13:04 +08:00
mcy
833cc55e26 FlatMessage没有默认构造方法json反序列化的问题
Dml类增加isDdl属性
2018-12-17 09:47:09 +08:00
agapple
689366248d Merge pull request #1289 from rewerma/master
rdb adapter增加mysql镜像db(schema)同步
2018-12-14 18:34:52 +08:00
mcy
3acdffb297 mirror schema 完成测试 2018-12-14 14:58:15 +08:00
mcy
fbf249580f mirror db 2018-12-14 11:30:41 +08:00
agapple
d2e3e19831 fixed issue #1282 , NPE 2018-12-13 12:52:59 +08:00
agapple
0523b68c26 fixed parse error 2018-12-12 10:48:22 +08:00
agapple
995a33a645 Merge pull request #1278 from WithLin/master
Update AddressUtils.java
2018-12-12 10:44:05 +08:00
mcy
5c4b1f6e63 modify 2018-12-12 10:11:06 +08:00
XiaoFu
ba5865683f Update AddressUtils.java 2018-12-12 10:03:49 +08:00
mcy
89a4943349 Merge branch 'master' into feature/rdb 2018-12-12 09:05:59 +08:00
agapple
35e0e882c1 fixed hash mode 2018-12-11 20:41:21 +08:00
agapple
0197482618 fixed partitionHash format 2018-12-11 20:17:08 +08:00
agapple
72bad4d54c Merge pull request #1272 from rewerma/master
去除的多余的依赖
2018-12-11 17:03:07 +08:00
mcy
48de904ee1 去掉 #1266 中增加的 protocol 的多余的依赖 2018-12-11 14:43:13 +08:00
rewerma
f6a931d8c6 Merge pull request #27 from alibaba/master
merge
2018-12-11 14:15:33 +08:00
agapple
277a273ebc fixed pull #1266 , optimizer code 2018-12-11 13:40:32 +08:00
agapple
bd5110b951 Merge pull request #1266 from rewerma/master
增加mq 分区规则配置正则表达式
2018-12-11 12:09:36 +08:00
machey
aeecf87490 去掉对before的判断,分区发送的表pk不能修改 2018-12-11 00:09:12 +08:00
machey
eac3f5ce5f 修改convert时设置pk 2018-12-10 23:54:07 +08:00
mcy
706ee88914 pattern表达式调整
pk缓存
2018-12-10 21:28:09 +08:00
agapple
7c63e81e01 fixed issue #1256, rds alibaba_rds_row_id 2018-12-10 14:42:28 +08:00
mcy
99a1123e01 整理代码 2018-12-10 09:52:48 +08:00
mcy
24d898d87a rdb 全schema同步 2018-12-10 09:25:40 +08:00
machey
5650b56bed 打印错误日志 2018-12-10 01:10:04 +08:00
machey
547cbf82c8 对原生message发送mq的分区支持 2018-12-10 01:03:18 +08:00
machey
03ee9c7ecf 根据主键Hash增加正则表达式支持,pk通配符指定自动获取支持 2018-12-10 00:09:49 +08:00
rewerma
ac738dae05 Merge pull request #26 from alibaba/master
merge
2018-12-09 22:06:29 +08:00
agapple
dda8081984 Merge pull request #1263 from tankilo/master
Linux启动脚本格式是DOS,需要转换成Unix格式
2018-12-08 13:26:52 +08:00
tankilo
f0fc37c43b switch file format from DOS to UNIX 2018-12-07 14:54:45 +08:00
tankilo
5a99de1fa9 switch file format from DOS to UNIX 2018-12-07 14:54:06 +08:00
agapple
ce956c980d add github template 2018-12-06 18:48:17 +08:00
agapple
c045dc244e optimizer filter 2018-12-06 10:50:12 +08:00
agapple
1b11aa1d21 fixed issue #1220, 解决一下no alive canal server重试过于频繁 2018-12-06 10:31:13 +08:00
rewerma
dac642f744 Merge pull request #25 from alibaba/master
merge
2018-12-03 17:55:32 +08:00
agapple
19e164b599 Merge pull request #1232 from rewerma/master
fixed #1229
2018-11-30 13:45:10 +08:00
mcy
339ecdd817 fixed #1229 2018-11-29 17:38:13 +08:00
rewerma
5fe7ae1613 Merge pull request #1228 from rewerma/master
rdb 关键字转译符过滤 fixed  #1224
2018-11-29 15:42:19 +08:00
mcy
65f2695963 rdb 关键字转译符过滤 2018-11-29 15:39:08 +08:00
mcy
cf5e42442b mysql jdbc依赖移到外部pom 2018-11-29 13:42:37 +08:00
agapple
e7b678d5e0 Merge pull request #1218 from rewerma/master
client打fat包排除其他包
2018-11-29 13:27:02 +08:00
mcy
f04447837c client打fat包排除其他 2018-11-29 10:21:27 +08:00
rewerma
b7d2ad2e18 Merge pull request #1208 from rewerma/master
fixed #1201
2018-11-27 22:40:47 +08:00
machey
f1710f1c7f fixed #1201 2018-11-27 22:39:49 +08:00
agapple
37094447b1 Merge pull request #1205 from rewerma/master
移除adapter pom中的parent fixed #1203
2018-11-27 19:41:42 +08:00
mcy
b97d377d83 移除adapter pom中的parent fixed #1203 2018-11-27 19:38:30 +08:00
agapple
46b6528273 fixed tablemeta check 2018-11-27 19:33:25 +08:00
agapple
6c3b3acde0 Merge pull request #1202 from DinoZhang/DinoZhang-patch-1
fix Datasource named ${DS_PROMETHEUS} was not found
2018-11-27 19:25:59 +08:00
DinoZhang
91b036a4fc fix Datasource named ${DS_PROMETHEUS} was not found 2018-11-27 17:34:08 +08:00
DinoZhang
67cd0e5fca Merge pull request #2 from alibaba/master
merge master
2018-11-27 17:10:57 +08:00
rewerma
9dfa5da7bc Merge pull request #24 from alibaba/master
merge
2018-11-27 11:53:47 +08:00
agapple
9bda60bf89 fixed pom 2018-11-26 14:29:13 +08:00
agapple
9aaf20fb5e [maven-release-plugin] prepare for next development iteration 2018-11-26 13:22:04 +08:00
agapple
8496ceaf15 [maven-release-plugin] prepare release canal-1.1.2 2018-11-26 13:21:51 +08:00
agapple
cf23e0ffea fixed javadoc 2018-11-26 13:11:24 +08:00
agapple
4e9e3f5abe fixed issue #1192 , NPE test 2018-11-25 21:17:34 +08:00
agapple
cbab3fb561 fixed issue #1168, support filter with compareTableMetaDbAndMemory 2018-11-25 21:01:19 +08:00
agapple
f7bf4ac6ff fixed log test 2018-11-25 18:33:34 +08:00
agapple
df4c66b9e2 Merge pull request #1193 from woshijay7788/feature_kafka_config
add max.request.size config
2018-11-25 11:55:51 +08:00
agapple
a6ee87281a Merge pull request #1194 from guixincui/master
修改抽象引用
2018-11-25 11:55:00 +08:00
guixincui
90dab6831b 修改接口引用 2018-11-24 23:40:18 +08:00
gl
839d5415fc add max.request.size config 2018-11-24 22:48:54 +08:00
agapple
29f03bf398 fixed batchSize calc 2018-11-24 15:34:39 +08:00
agapple
ec235f3efd fixed rocketmq ak/sk 2018-11-23 09:56:55 +08:00
rewerma
3b25b3b342 Merge pull request #23 from alibaba/master
merge
2018-11-22 09:04:24 +08:00
agapple
aa89453bf6 fixed adapter 2018-11-21 22:49:22 +08:00
agapple
cc97f3b331 Merge pull request #1171 from rewerma/master
adapter 分批同步
2018-11-21 22:09:33 +08:00
agapple
89ec3037d4 Merge pull request #1173 from RickJou/master
等号两边都有空格
2018-11-21 21:48:15 +08:00
mcy
e711f1a091 rdb 并行提交 2018-11-21 16:57:02 +08:00
Alan
ad18e0335d 等号两边都有空格
格式保持一致,看起来更像大厂出品  ^_^
2018-11-21 16:31:46 +08:00
mcy
67cc73b8e2 adapter 配置修改 2018-11-21 14:26:19 +08:00
agapple
638952fad1 fixed binlog seek & aliyun ak/sk 2018-11-21 13:51:34 +08:00
mcy
56ec66f90e adapter 分批同步 2018-11-21 13:46:30 +08:00
agapple
c0bbe530f1 Merge pull request #1169 from ymwneu/supportRocketMQ
[ISSUE#1109]Support aliyun RocketMQ
2018-11-21 12:51:31 +08:00
maowei.ymw
4bfc476e08 Modify rocketMQ related pom 2018-11-21 10:44:58 +08:00
rewerma
5d71d50d4e Merge pull request #22 from alibaba/master
merge
2018-11-20 20:08:11 +08:00
agapple
26700f3005 fixed batch sync dml 2018-11-20 19:01:07 +08:00
agapple
a7be9c75f9 fixed mysql rotate checksum 2018-11-20 18:29:01 +08:00
agapple
b6f1e0d13c fixed rocketmq ack npe 2018-11-20 17:14:29 +08:00
maowei.ymw
50630cc934 Support client connect rocketmq in aliyun 2018-11-19 14:33:59 +08:00
agapple
43db5bec97 Merge pull request #1155 from rewerma/master
es readme.md
2018-11-18 12:51:29 +08:00
mcy
affd598470 es readme.md 2018-11-17 21:18:48 +08:00
agapple
178bea07a8 Merge pull request #1154 from rewerma/master
adapter 配置修改动态加载
2018-11-17 15:29:00 +08:00
mcy
fcdf95b5ec rdb 批量提交超时提交 2018-11-17 04:37:46 +08:00
mcy
991418ce6e 修改rdb批量提交分批的问题 2018-11-16 22:53:10 +08:00
mcy
d34bee3359 adapter 配置修改动态加载 2018-11-16 18:07:32 +08:00
agapple
0a3c1645e8 Merge pull request #1153 from rewerma/master
rdb 批量提交优化
2018-11-16 14:07:23 +08:00
mcy
9dc4d78b3b fix 2018-11-16 13:24:36 +08:00
mcy
bc056288d4 rdb 批量提交优化 2018-11-16 13:12:50 +08:00
agapple
8aea31232b Merge pull request #1151 from rewerma/master
将oracle mssql pgsql 的jdbc打包进lib
2018-11-16 10:16:26 +08:00
machey
fc6c871382 Merge branch 'master' into feature/mcy
# Conflicts:
#	client-adapter/rdb/pom.xml
2018-11-16 00:06:56 +08:00
machey
14c0e4535a 将oracle mssql pgsql 的jdbc打包进lib 2018-11-15 23:59:16 +08:00
mcy
7ee7ba0e05 rdb 批量提交 2018-11-15 22:47:08 +08:00
agapple
7992b883d2 fixed binlog checksum 2018-11-15 19:40:23 +08:00
agapple
5bc0c3f06f Merge pull request #1147 from rewerma/master
rdb 批量并行提交
2018-11-15 19:28:29 +08:00
mcy
b457ecd387 adapter 主配置application.yml动态加载 2018-11-15 17:09:53 +08:00
mcy
997646b2db 指定是否按主键hash并行同步, 否则按表名hash表间并行同步 2018-11-15 10:39:34 +08:00
mcy
915849b83a 预留sync(MappingConfig config, List<Dml> dmlList)方法
pk hash以old pk值为准若存在
2018-11-14 20:26:38 +08:00
agapple
129118b483 Merge pull request #1149 from spccold/master
filter views when dumpTableMeta
2018-11-14 19:50:41 +08:00
wuwo
aa68408c53 filter views when dumpTableMeta 2018-11-14 19:21:34 +08:00
mcy
d396a0b65c rdb 批量提交 2018-11-14 18:21:50 +08:00
mcy
827b872cf8 rdb 批量并行提交 2018-11-14 18:05:55 +08:00
agapple
6f3cae5ddf Merge pull request #1143 from rewerma/master
配置整理
2018-11-14 16:54:29 +08:00
mcy
31bf92ec8e 配置整理 2018-11-14 11:49:22 +08:00
mcy
68d8aee6c3 配置整理 2018-11-14 11:32:01 +08:00
mcy
c376f0afd2 配置中增加 canal.mq.acks canal.mq.compressionType 2018-11-14 11:14:32 +08:00
mcy
60e5554125 修改bootstrapServers为mqServers 2018-11-14 11:00:55 +08:00
mcy
241c43a894 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	client-adapter/common/src/main/java/com/alibaba/otter/canal/client/adapter/support/ExtensionLoader.java
2018-11-14 10:50:11 +08:00
rewerma
fecc112196 Merge pull request #21 from alibaba/master
merge
2018-11-14 10:48:04 +08:00
agapple
dd04577994 Merge pull request #1142 from spccold/master
let tsdbSnapshotInterval config work correctly
2018-11-13 22:04:16 +08:00
agapple
51a299259b Merge pull request #1141 from Renkai/compression_type
Kafka增加参数acks和compressionType
2018-11-13 22:03:00 +08:00
wuwo
0a0a39880c Merge remote-tracking branch 'upstream/master' 2018-11-13 20:54:45 +08:00
wuwo
5ad9cf3f16 let tsdbSnapshotInterval config work correctly 2018-11-13 20:54:36 +08:00
mcy
d29fe5b04e 去掉调试代码 2018-11-13 20:01:20 +08:00
agapple
20062d861d fixed test code 2018-11-13 19:59:18 +08:00
agapple
73de8b32a9 Merge pull request #1140 from rewerma/master
adapter plugin
2018-11-13 19:51:36 +08:00
Renkai
8af1301062 Kafka增加参数acks和compressionType 2018-11-13 18:29:25 +08:00
mcy
8c3ade2d50 外部adapter plugin文件夹 2018-11-13 17:40:12 +08:00
rewerma
752a3cd66a Merge pull request #20 from alibaba/master
merge
2018-11-13 14:13:41 +08:00
agapple
154ba422f2 fixed plugin 2018-11-13 14:10:48 +08:00
agapple
03a9522191 fixed event 2018-11-13 13:41:19 +08:00
agapple
c4947cad3c Merge pull request #1133 from spccold/master
fix MemoryTableMeta#processTableElement bug
2018-11-13 11:34:15 +08:00
wuwo
3f8cdafea3 fix MemoryTableMeta#processTableElement bug 2018-11-13 11:14:37 +08:00
agapple
fcaf8e88f8 Merge pull request #1132 from rewerma/master
rdb adapter整理
2018-11-13 09:18:27 +08:00
mcy
e7ab25f819 增加rdb adapter说明 2018-11-12 18:26:34 +08:00
mcy
b45a27e231 db同步代码整理 2018-11-12 18:01:52 +08:00
mcy
2e5b7b89af 简化adapter配置 2018-11-12 17:30:40 +08:00
mcy
66912d3d05 rdb etl count destination 接口适配
es hbase 多源适配
2018-11-12 15:07:46 +08:00
agapple
ec1ac6d11c Merge pull request #1131 from rewerma/master
rdb同步适配多数据源
2018-11-12 10:25:37 +08:00
machey
7cca8857ff README.md 修改 2018-11-11 19:56:14 +08:00
machey
e7086415f8 rdb专用的的ClassExtensionLoader,默认canal client logger example配置 2018-11-11 19:44:30 +08:00
machey
4a27d81da1 Merge branch 'master' of https://github.com/rewerma/canal 2018-11-11 18:34:46 +08:00
rewerma
739425e99c Merge pull request #19 from alibaba/master
merge
2018-11-11 18:33:46 +08:00
agapple
cc1574d913 fixed adapter 2018-11-11 01:15:02 +08:00
machey
d7ab6e2dc1 rdb同步适配多数据源 2018-11-10 23:55:09 +08:00
agapple
808bedf984 Merge pull request #1128 from spccold/master
fixed DatabaseTableMeta#compareTableMeta
2018-11-10 12:17:09 +08:00
agapple
357eb885b2 Merge pull request #1127 from rewerma/master
canal server端 MQ 配置修改
2018-11-10 12:16:31 +08:00
wuwo
417e04f655 fixed DatabaseTableMeta#compareTableMeta 2018-11-09 19:23:03 +08:00
mcy
2d41bb9960 修改mq配置针对destination级别重启 2018-11-09 18:19:51 +08:00
mcy
7d7c82ce91 修改mq配置针对destination级别重启 2018-11-09 18:12:04 +08:00
mcy
0c3f7a806e 代码整理 2018-11-09 17:06:42 +08:00
mcy
2a38bca34b 代码整理 2018-11-09 16:52:34 +08:00
mcy
c5bd42bbf1 canal server端 MQ 配置修改
MQ配置可动态加载
2018-11-09 16:39:52 +08:00
agapple
8c1f15a49e Merge pull request #1126 from rewerma/master
关系型数据同步adapter, 支持 mysql oracle postgresql sqlserver
2018-11-09 15:26:07 +08:00
agapple
f9778a0aff fixed issue #1087, support kafka docker check 2018-11-09 13:58:39 +08:00
mcy
2ac84b4320 关系型数据同步adapter, 支持 mysql oracle postgresql sqlserver 2018-11-08 19:34:15 +08:00
jiangahng.loujh
0677443ccf fixed issue #1100 , fix type compare 2018-11-08 13:57:12 +08:00
jiangahng.loujh
2c1f3e649a fixed issue #1107 , more info message 2018-11-08 13:50:23 +08:00
agapple
4faf5428b1 Merge pull request #1120 from rewerma/master
flagMessage json 序列化无null值的bug
2018-11-08 13:39:09 +08:00
mcy
b71472661b Merge branch 'master' into feature/mcy 2018-11-08 11:23:47 +08:00
mcy
6fa111866f flagMessage json 序列化无null值的bug 2018-11-08 11:22:34 +08:00
mcy
f7ea8df89e rdb新增同步测试完成 2018-11-08 11:19:50 +08:00
agapple
041225c3f2 Merge pull request #1118 from littleneko/patch-1
fix: buildLastTransactionPosition 的 for 循环少了 =0
2018-11-07 21:58:30 +08:00
agapple
a8d708ea1b Merge pull request #1116 from spccold/master
a little improvement for DatabaseTableMeta
2018-11-07 21:55:54 +08:00
mcy
5ae7112192 init rdb sync 2018-11-07 21:01:50 +08:00
littleneko
2278340c7b fix: buildLastTransactionPosition 的 for 循环少了 =0 2018-11-07 20:24:38 +08:00
wuwo
87abaee8a7 a little improvement for DatabaseTableMeta 2018-11-07 15:50:33 +08:00
agapple
8f2e2b9ccd Merge pull request #1108 from spccold/master
skip tsdb snapshot apply if has not receive new ddl change from last …
2018-11-07 15:01:43 +08:00
agapple
d2ecb0aad9 Merge pull request #1112 from rewerma/master
client 排除jsr305不打进fat jar
2018-11-07 15:00:40 +08:00
mcy
1126d26574 Merge branch 'master' into feature/mcy 2018-11-07 11:40:06 +08:00
mcy
b71e299161 kafka单个partition的发送未改为同步发送的bug fix 2018-11-07 11:37:16 +08:00
mcy
572ea9f27a Merge branch 'master' into feature/mcy 2018-11-07 09:34:00 +08:00
mcy
bc298bedd5 支持hbase rowkey指定数字长度 2018-11-07 09:32:52 +08:00
mcy
202557630c 调整etl锁的粒度 2018-11-07 09:05:47 +08:00
machey
c27d5fa162 ETL整个destination,同步开关无效的问题 2018-11-07 02:04:08 +08:00
machey
3090557eeb client 排除jsr305不打进fat jar 2018-11-06 23:16:11 +08:00
machey
6de9f7efa7 修改 adapter release 打包名称 2018-11-06 22:49:34 +08:00
wuwo
f2b8d000f7 skip tsdb snapshot apply if has not receive new ddl change from last snapshot time 2018-11-06 16:59:44 +08:00
agapple
8ee546d34d Merge pull request #1106 from rewerma/master
修改adapter打包,启动方式
2018-11-06 16:24:31 +08:00
mcy
5b94c69d10 修改adapter打包,启动方式 2018-11-06 14:52:17 +08:00
mcy
8ae192f0a9 adapter canal-client 版本 2018-11-06 09:56:16 +08:00
rewerma
2e1a1c31e6 Merge pull request #18 from alibaba/master
merge
2018-11-06 09:50:11 +08:00
agapple
238da873b2 Merge pull request #1104 from jiacheo/master
修复rocketmq&kafka 发送消息失败时回滚后继续提交的问题
2018-11-05 23:08:34 +08:00
jiacheo
edb5f294ef fix:rollback之后继续commit,会产生 CanalServerException: ack error , clientId:1001 batchId:12 is not exist , please check 的错误。 2018-11-05 22:00:56 +08:00
agapple
5a76e2aa58 Merge pull request #1103 from wingerx/master
增加alter rename 的ddl 类型为rename
2018-11-05 19:50:20 +08:00
winger
1e20cac0da Merge remote-tracking branch 'upstream/master' 2018-11-05 18:39:47 +08:00
winger
d8e411462e 增加alter rename 的类型为rename 2018-11-05 18:38:44 +08:00
agapple
59e65ed4a6 Merge pull request #1099 from spccold/master
destory TableMetaTSDB when stop EventParser
2018-11-05 17:39:50 +08:00
agapple
4319b5e888 Merge pull request #1098 from rewerma/master
ES Adapter 支持
2018-11-05 17:32:26 +08:00
mcy
0d9695c3a5 增加对array和object类型的支持 2018-11-05 17:29:11 +08:00
七锋
359aa1a074 fixed compiler failed 2018-11-05 16:53:15 +08:00
wuwo
e608f09b53 improve DatabaseTableMeta 2018-11-05 16:37:42 +08:00
wuwo
beed10901d destory TableMetaTSDB when stop EventParser 2018-11-05 16:22:15 +08:00
mcy
dab6fa5aa1 Merge branch 'master' of https://github.com/rewerma/canal 2018-11-05 15:31:41 +08:00
rewerma
30d20f824b Merge pull request #17 from alibaba/master
merge
2018-11-05 15:31:02 +08:00
mcy
80cf533b05 整理注释 2018-11-05 15:24:32 +08:00
七锋
6ff57f53f8 fixed issue #1070, support mysql8.0.13 2018-11-05 15:06:40 +08:00
mcy
650446de5b etl实现 2018-11-05 13:36:35 +08:00
mcy
347601b9fe 同步测试类 2018-11-05 11:40:27 +08:00
mcy
5c8a5998d9 修改外键 2018-11-05 10:06:45 +08:00
mcy
391e040c6a 删除测试完成
后续: 修改 删除外键的情况, 修改主键的情况适配
2018-11-02 17:19:52 +08:00
七锋
8597d9e926 fixed more info 2018-11-02 12:51:36 +08:00
agapple
a895ce666e Merge pull request #1090 from jiacheo/master
CanalMessageDeserializer.deserializer 方法和FlatMessage.messageConverter 配合的问题
2018-11-02 11:10:22 +08:00
mcy
9d113dbc13 Merge branch 'master' into feature/mcy
# Conflicts:
#	client-adapter/launcher/src/main/resources/application-sample.yml
#	client-adapter/launcher/src/main/resources/application.yml
2018-11-02 11:08:57 +08:00
mcy
5cc2f8f9f7 增加file的path读取 2018-11-02 11:07:41 +08:00
mcy
5b9ada1f8c 修改测试完成 2018-11-02 09:51:30 +08:00
jiacheo
369059fa39 Merge pull request #1 from jiacheo/fix-lazyParseEntry-raw-wrong-value
Update CanalMessageDeserializer.java
2018-11-02 01:53:08 +08:00
jiacheo
9473f4e8fd Update CanalMessageDeserializer.java
fix lazyParseEntry 'raw' wrong value.
2018-11-02 01:48:17 +08:00
rewerma
685053599f Merge pull request #1086 from rewerma/master
release包不打进application.yml
2018-11-01 23:44:41 +08:00
machey
a9727cf267 release包不打进application.yml 2018-11-01 23:43:53 +08:00
agapple
bc399ba9f9 Merge pull request #1069 from spccold/master
pass useDruidDdlFilter parameter to LogEventConvert
2018-11-01 22:58:01 +08:00
mcy
81f403a9f2 更新完成 2018-11-01 21:07:45 +08:00
wuwo
332f759f96 filter dml before apply to tsdb 2018-11-01 17:38:18 +08:00
wuwo
5d5aafb7cd Merge remote-tracking branch 'upstream/master' 2018-11-01 17:28:29 +08:00
mcy
f42f7cfe72 Merge branch 'master' into feature/mcy
# Conflicts:
#	client-adapter/launcher/src/main/resources/application.yml
2018-11-01 16:39:56 +08:00
mcy
96b9484f70 modify 2018-11-01 16:37:47 +08:00
七锋
3bb408194d fixed issue #1081 , support mariadb rotate_event support checksum 2018-11-01 16:03:40 +08:00
mcy
865ba94605 application.yml配置打包设置默认模板 2018-11-01 15:22:14 +08:00
mcy
bb883cd228 Merge branch 'master' into feature/mcy 2018-11-01 14:53:51 +08:00
rewerma
d3e1ddd234 Merge pull request #1084 from rewerma/master
fix #1083
2018-11-01 14:47:33 +08:00
mcy
b9c4884af1 fix #1083 2018-11-01 14:46:29 +08:00
mcy
a6b16eedfa modify 2018-11-01 14:43:59 +08:00
mcy
9d04a82c42 新增完成 2018-11-01 14:32:11 +08:00
mcy
c9ad18894d 从表插入, 主表为简单字段 2018-11-01 11:33:12 +08:00
mcy
b2b44555ca 从表插入, 主表为简单字段 2018-11-01 11:07:35 +08:00
mcy
14e094b522 modify 2018-10-31 18:47:16 +08:00
agapple
0dea4b7944 Merge pull request #1079 from rewerma/master
application.yml不打包进jar
2018-10-31 17:34:33 +08:00
mcy
94a3cfa9de Merge branch 'master' into feature/mcy 2018-10-31 17:18:57 +08:00
mcy
ed1feb9502 application.yml不打包进jar, 解决jar中的application.yml和config中的会合并bug 2018-10-31 16:58:50 +08:00
mcy
a4856b9a73 modify 2018-10-31 16:55:48 +08:00
七锋
ff3ccde62a fixed rds binlog dump 2018-10-31 14:25:54 +08:00
mcy
2a2977eca7 主表带函数新增 2018-10-31 14:00:06 +08:00
七锋
1d9e2ccedd fixed issue #1076 , support rds binlog expired 2018-10-31 12:51:02 +08:00
七锋
dd8243a56d fixed issue #1075, support message transactor filter 2018-10-30 23:48:05 +08:00
mcy
2c9acb655d 单表新增 2018-10-30 19:52:05 +08:00
mcy
e1191b665e es配置加载 2018-10-30 15:57:00 +08:00
mcy
e4e23c9ecd 增加adapter相关参数: retry timeout batchSize 2018-10-30 14:13:51 +08:00
wuwo
4ce2b94241 rollback tsdb change 2018-10-30 11:49:49 +08:00
mcy
11ac253c46 adapter pom整理 2018-10-30 10:12:19 +08:00
mcy
1d2e85672c elasticsearch适配器 2018-10-30 09:49:04 +08:00
mcy
82b8b56aa3 partition默认为空 2018-10-30 09:10:49 +08:00
mcy
4e18d7800a 拼写错误 2018-10-30 09:08:34 +08:00
rewerma
7efd067bd5 Merge pull request #16 from alibaba/master
merge
2018-10-29 20:14:36 +08:00
wuwo
4c7129115c a little improve about tsdb 2018-10-29 17:49:34 +08:00
wuwo
0f14ed926b pass useDruidDdlFilter parameter to LogEventConvert 2018-10-29 17:32:10 +08:00
七锋
be5f1546ca fixed issue #1063 , rocketmq bugfix 2018-10-29 16:56:29 +08:00
agapple
f3160bf6cb Merge pull request #1065 from f-zhao/zhaofeng-branch
fix: fix NPE, 使用CanalServerWithManager时,开启GTID模式下,不传入masterPosition的情…
2018-10-29 16:42:46 +08:00
赵峰
fa79db65b7 fix: fix NPE, 使用CanalServerWithManager时,开启GTID模式下,不传入masterPosition的情况下,会产生NPE 2018-10-29 16:18:12 +08:00
七锋
d134aa0c20 fixed adjust default value 2018-10-29 15:59:32 +08:00
七锋
b9f40f326f [maven-release-plugin] prepare for next development iteration 2018-10-29 14:57:39 +08:00
七锋
774aeeea68 [maven-release-plugin] prepare release canal-1.1.1 2018-10-29 14:57:25 +08:00
七锋
f28efce11e fixed javadoc for release 2018-10-29 14:54:17 +08:00
七锋
d03e7e2b15 fixed canal_version release 2018-10-29 13:49:24 +08:00
七锋
56ed158814 fixed issue #850 , support alter lock/algorithm 2018-10-29 12:46:20 +08:00
rewerma
166a9a7f8f Merge pull request #1059 from rewerma/master
CanalConnector接口去掉stopRunning方法
2018-10-29 01:42:30 +08:00
mcy
b131e8cfa4 CanalConnector接口去掉stopRunning接口 2018-10-29 01:40:34 +08:00
mcy
2e1d0e36c5 group 线程池在父类初始化 2018-10-29 01:05:12 +08:00
agapple
ddcf619deb Update README.md 2018-10-28 23:39:11 +08:00
rewerma
8f1b66ab5a Merge pull request #1057 from rewerma/master
kafka canal-adapter 分布式开关的bug
2018-10-28 22:36:56 +08:00
mcy
167858cd95 解决分布式同步开关关闭同步状态下,
重启 kafka canal-adapter后在开启同步,丢失数据的bug
2018-10-28 22:35:32 +08:00
rewerma
04e56fb94c Merge pull request #1056 from rewerma/master
group 线程池没有初始化的bug
2018-10-28 21:50:53 +08:00
mcy
00fce30072 group 线程池没有初始化的bug 2018-10-28 21:50:19 +08:00
rewerma
423392a18a Merge pull request #1055 from rewerma/master
代码整理
2018-10-28 21:33:46 +08:00
mcy
cdb34571ab adapter readme 修改 2018-10-28 21:31:57 +08:00
mcy
3b4d28eec3 测试修改 2018-10-28 21:30:54 +08:00
mcy
297122f47f Merge branch 'master' of https://github.com/rewerma/canal 2018-10-28 21:19:53 +08:00
rewerma
f9ff05f16c Merge pull request #15 from alibaba/master
merge
2018-10-28 21:17:04 +08:00
七锋
071545987b fixed mq config 2018-10-28 21:15:57 +08:00
七锋
c36a51b8e3 fixed client-adpater logger test 2018-10-28 20:29:00 +08:00
七锋
232bbaf6d4 fixed group name 2018-10-28 19:58:07 +08:00
七锋
a0b38a9cac fixed MQConnector 2018-10-28 19:52:26 +08:00
agapple
d76367584c Merge pull request #1054 from duhengforever/canal_rocketmq_flatmessage
[ISSUE1027]Add flat message support to rocketmq
2018-10-28 17:37:38 +08:00
duhengforever
86fd77f9c4 Resolve conflict 2018-10-28 17:00:33 +08:00
duhengforever
ebaf78f5aa Resolve conflict with master branch 2018-10-28 16:18:13 +08:00
duhengforever
b484593869 Add flat message support to rocketmq 2018-10-28 16:09:31 +08:00
mcy
a7bf6258f7 hbase类型转换工具类整理 2018-10-27 22:23:41 +08:00
rewerma
2c6bd3ee1b Merge pull request #1050 from rewerma/master
修改hbase配置项名
2018-10-27 20:05:41 +08:00
mcy
87ac3daecc 修改hbase配置项名 2018-10-27 20:03:26 +08:00
七锋
fd7b9d766a fixed snapshot expire 2018-10-27 00:47:50 +08:00
七锋
f822761ab2 fixed issue #1047 , support snapshot expire 2018-10-26 23:46:41 +08:00
七锋
1e2cf9d476 fixed bit(8) with value 255 2018-10-26 21:51:19 +08:00
七锋
2d930894ff fixed issue #1046, tinyint(1) unsigned with value 255 2018-10-26 21:50:12 +08:00
rewerma
30b7de7233 Merge pull request #1045 from rewerma/master
修改打包配置
2018-10-26 15:57:07 +08:00
mcy
0d22dbc982 修改打包配置 2018-10-26 15:56:05 +08:00
rewerma
8446e17703 Merge pull request #14 from alibaba/master
merge
2018-10-26 14:59:39 +08:00
七锋
fb936f896e fixed client-launcher deploy 2018-10-26 14:57:52 +08:00
mcy
0d0fcbbc0b 修改HBase适配器配置 2018-10-26 14:03:29 +08:00
rewerma
5cfbc6b91d Update README.md 2018-10-26 13:36:59 +08:00
rewerma
3b1f6ce4fb Update README.md 2018-10-26 13:25:40 +08:00
rewerma
fd3927ce3e Merge pull request #1042 from rewerma/master
canal adapter readme.md
2018-10-26 13:24:36 +08:00
mcy
bbfd4b4996 canal-adapter readme.md 2018-10-26 13:23:22 +08:00
mcy
848cbe11dd 代码整理 2018-10-26 10:33:16 +08:00
rewerma
f7185a618b Merge pull request #1039 from rewerma/master
规范注释
2018-10-25 21:24:30 +08:00
mcy
d70dc8b88c 规范注释 2018-10-25 21:21:06 +08:00
agapple
b5f5d3f0f0 Merge pull request #1037 from rewerma/master
完善adapter-launcher及hbase-adaper相关功能
2018-10-25 20:19:48 +08:00
mcy
ddfc2464f3 etl 增加同步锁 2018-10-25 17:43:11 +08:00
mcy
c3402a97f3 etl 增加同步锁 2018-10-25 17:34:15 +08:00
mcy
6ee6b3c398 同步分布式开关 2018-10-25 16:43:33 +08:00
mcy
42a4abe4c7 HBase etl锁定同步等待 2018-10-25 14:24:33 +08:00
mcy
0f1334c92c 加入同步开关 2018-10-25 13:52:52 +08:00
七锋
346d091d00 fixed issue #1032 , support raw config 2018-10-25 13:11:34 +08:00
mcy
27dba9ec1b HBase根据datasourceKey导入 2018-10-25 10:52:55 +08:00
mcy
8dbf63e436 增加adapter assembly打包 2018-10-25 10:05:05 +08:00
mcy
30a11c75cb HBase的etl初步完成 2018-10-24 20:47:25 +08:00
mcy
49caff5759 HBase的etl初步完成 2018-10-24 19:12:16 +08:00
mcy
0a7251add0 HBase的etl初步完成 2018-10-24 18:30:42 +08:00
七锋
b5dac60cbb fixed cliet-adapter artifactId 2018-10-24 17:00:56 +08:00
七锋
9270834631 fixed rds ak/sk config for manager 2018-10-24 16:46:26 +08:00
七锋
575dd59c78 fixed mysql set(8 bit) type parse 2018-10-24 16:25:28 +08:00
mcy
15e79c1400 调整Hbase适配 2018-10-24 15:40:48 +08:00
七锋
c75c248086 fixed issue #1019 , support canal embedded with Entry 2018-10-24 13:45:58 +08:00
rewerma
741f6310b3 Merge pull request #13 from alibaba/master
merge
2018-10-24 13:25:15 +08:00
rewerma
2202ec451a Merge pull request #1028 from ttting/master
Fix Kafka FlatMessage Model Null Value set to ""
2018-10-24 12:58:00 +08:00
rewerma
1830458b6b Merge pull request #1031 from rewerma/master
新增adapter-launcher工程
2018-10-24 12:56:55 +08:00
mcy
1b88430f71 去掉client-launcher, 移入client-adapter中重命名为example, 调整其他相关模块结构 2018-10-24 12:55:42 +08:00
mcy
bbb4c4347e 修改adapter-launcher模块名为launcher 2018-10-24 12:44:19 +08:00
mcy
0ee46ad70e jar包依赖调整 2018-10-24 11:49:58 +08:00
mcy
243e129710 jar包依赖调整 2018-10-24 11:43:36 +08:00
mcy
a91f204682 新增adapter-launcher springboot工程 2018-10-24 11:29:28 +08:00
titeng.jiang
5bc5eec85e Fix Kafka FlatMessage Model Null Value set to "" 2018-10-24 10:02:50 +08:00
agapple
80d3781d81 Update README.md 2018-10-23 23:27:42 +08:00
agapple
b1e2ab4448 Update README.md 2018-10-23 23:25:05 +08:00
rewerma
3e49e33f9f Merge pull request #12 from alibaba/master
merge
2018-10-23 15:38:45 +08:00
agapple
986840b6bf Merge pull request #1014 from wingerx/master
修复通过`show master status`获取到多个GTID 时,回车符导致UUID 解析失败的bug
2018-10-19 12:57:47 +08:00
winger
61aea888f6 Merge remote-tracking branch 'upstream/master' 2018-10-19 10:30:16 +08:00
winger
c16037122b 修复通过show master status获取到多个GTID 时,回车符导致UUID 解析失败的bug 2018-10-19 10:27:50 +08:00
七锋
a823b909ad upgrade spring version 3.2.18 2018-10-17 18:35:32 +08:00
七锋
5d55c7ac00 fixed fastsql upgrade 2018-10-17 15:43:26 +08:00
rewerma
75f380252e Merge pull request #11 from alibaba/master
merge
2018-10-17 00:48:03 +08:00
七锋
5eb67990ca fixed es reset 2018-10-16 16:57:57 +08:00
七锋
017fe87e4b fixed issue #928, support Dml.executeTime 2018-10-16 16:55:30 +08:00
七锋
fc050c3ce9 fixed issue #980 , support TSDB dup column 2018-10-16 16:45:25 +08:00
七锋
b893aafae7 fixed issue #1001 , support docker restart 2018-10-16 13:33:45 +08:00
七锋
9c24b26d02 fixed gtid 2018-10-16 13:29:53 +08:00
agapple
22d1fc98ee Merge pull request #1006 from WithLin/patch-2
support  golang canal client  address  link
2018-10-16 13:12:43 +08:00
agapple
d88f204a15 Merge pull request #1002 from wallellen/fix-release-threadpool
1. AbstractEventParser 中应该对multiStageCoprocess每次在while最后进行stop而不是rese…
2018-10-16 11:36:28 +08:00
XiaoFu
5d0f79932a Update README.md 2018-10-15 18:36:08 +08:00
wallellen
7c44e5933d 1. AbstractEventParser 中应该对multiStageCoprocess每次在while最后进行stop而不是reset, reset会在mysqlMultiStageCoprocessor中重新创建两个线程池, 如果在dump出错的情况下, 会无限多的创建multiStageCoprocess而且不释放
2. MySqlMultiStageComprocessor中需要判断是否已经shutdown, 实际情况中存在shutdown为true而terminal一直为false的情况
2018-10-12 18:27:32 +08:00
agapple
4d36c60738 Merge pull request #990 from shicmV5/master
增加 目标数据库密码加密解密,采用druid方式进行加密解密,并设置canal.instance.enableDruid=true时,请使…
2018-10-09 22:15:46 +08:00
shichengming
53c2a02124 增加 目标数据库密码加密解密,采用druid方式进行加密解密,并设置canal.instance.enableDruid=true时,请使用druid加密数据库密码。false时,就是使用明文密码。 2018-10-09 16:49:33 +08:00
agapple
1701a4c97c Merge pull request #981 from rewerma/master
client模块中rocketmq-client包scope provide,外部使用单独依赖
2018-10-08 10:29:46 +08:00
mcy
e4b6385dcc 调整kafka同步发送和消费,确保消息不丢失 2018-10-03 16:32:08 +08:00
mcy
2e92ec3e4d client模块中rocketmq-client包scope provide,外部使用单独依赖 2018-10-03 12:27:56 +08:00
rewerma
d20485027f Merge pull request #10 from alibaba/master
merge
2018-10-03 12:09:49 +08:00
七锋
eb2a83b975 fixed test 2018-09-30 11:33:48 +08:00
七锋
9344ed121f format & import 2018-09-30 10:52:41 +08:00
agapple
c3327e567e Merge pull request #973 from duhengforever/develop_rocketmq
[ISSUE 800]提供RocketMQ原生接入canal
2018-09-30 10:28:37 +08:00
duhengforever
3ed8987779 Remove useless log print 2018-09-30 09:49:13 +08:00
duhengforever
fa8588f766 Modify canal-client config and polish consumer implementation 2018-09-30 09:40:05 +08:00
rewerma
fa8ffb8e66 Merge pull request #9 from alibaba/master
merge
2018-09-29 15:52:23 +08:00
agapple
9da8f9cc5a Merge pull request #969 from WithLin/patch-1
Fix link error
2018-09-29 13:50:55 +08:00
duhengforever
af03f07cc7 Modify default config 2018-09-27 19:39:46 +08:00
duhengforever
5ae16b1c7c Merge canal repo master 2018-09-27 17:09:00 +08:00
duhengforever
a37a7ff142 Add RocketMQ example and polish mq abstract class 2018-09-27 10:34:17 +08:00
agapple
ff592758cf Merge pull request #970 from wingerx/master
fix bug #968
2018-09-26 13:13:27 +08:00
winger
b04446d24d Merge remote-tracking branch 'upstream/master' 2018-09-25 18:46:39 +08:00
winger
40f8c931c7 fix bug #968: 对于workpool与BatchEventProcessor需要手动调用halt(),否则会导致其使用的工作线程(池)无法正常关闭(parserExecutor/stageExecutor.shutdownNow()无效) 2018-09-25 18:46:10 +08:00
XiaoFu
a22517adc2 Fix link error 2018-09-25 17:53:54 +08:00
duhengforever
821f3eced5 Add mq adapter
Signed-off-by: duhengforever <duhengforever@gmail.com>
2018-09-25 10:22:31 +08:00
七锋
00ec70d425 fixed readme 2018-09-21 15:45:52 +08:00
七锋
9d48d23787 fixed readme 2018-09-21 15:44:03 +08:00
七锋
9535e82da6 fixed readme 2018-09-21 15:40:18 +08:00
agapple
fd80f953e9 Update README.md 2018-09-21 15:30:35 +08:00
agapple
05718a9f20 Merge pull request #958 from rewerma/master
kafka生产端增加按pk hash到对应partition功能
2018-09-21 15:10:01 +08:00
mcy
19b7f730b6 整理代码 2018-09-20 18:06:47 +08:00
mcy
4f2b4cea53 整理代码 2018-09-20 17:25:32 +08:00
mcy
e566160f1e 整理代码 2018-09-20 17:24:32 +08:00
mcy
74890050d0 kafka生产端增加按pk hash到对应partition功能 2018-09-20 16:48:14 +08:00
mcy
0cda90cdea 默认将数据发现kafka的partition 0,避免多分区的数据一致性问题
后续将支持通过id hash分发数据
2018-09-20 16:17:38 +08:00
rewerma
1a11153cd2 Merge pull request #8 from alibaba/master
merge
2018-09-20 16:03:43 +08:00
duhengforever
d5aa324ce4 Add RocketMQ canal connector 2018-09-20 15:48:52 +08:00
七锋
09df602f3b support filterTransactionEntry 2018-09-20 11:30:10 +08:00
agapple
b026c44ea8 Merge pull request #953 from DaiZZZZZ/master
单词拼写修正
2018-09-20 10:15:23 +08:00
zhikuodai
19f765df77 单词拼写修正 2018-09-19 15:16:38 +08:00
rewerma
4e1675033a Merge pull request #7 from alibaba/master
merge
2018-09-18 10:18:32 +08:00
rewerma
e9439125bd Merge branch 'master' into master 2018-09-18 10:18:22 +08:00
agapple
a11f9e4b34 Merge pull request #949 from WithLin/master
Fix simpleCanalConnector bug
2018-09-18 10:06:44 +08:00
agapple
10b0ade627 Merge pull request #947 from lcybo/master
修复group模式报错
2018-09-17 19:51:12 +08:00
WithLin
1a8d6e65cf FIx 2018-09-17 11:18:00 +08:00
WithLin
9748fceda8 fix proto3 bug 2018-09-17 11:11:30 +08:00
mcy
7005c11ac2 fix序列化的一些问题, kafka生产端统一使用异步 2018-09-17 11:10:50 +08:00
XiaoFu
88bf2ae64d Merge pull request #3 from alibaba/master
merge local repo
2018-09-17 10:55:55 +08:00
Chuanyi Li
cae6df1457 Update grafana tmpl. 2018-09-15 13:28:27 +08:00
Chuanyi Li
6682c56b9f Canal metrics group mode support. 2018-09-15 13:21:38 +08:00
agapple
5394613ba6 Merge pull request #942 from wingerx/master
增加当前的gtid相关信息至Entry Header
2018-09-14 16:53:41 +08:00
winger
6e84b98651 example 增加获取当前gtid相关信息示例 2018-09-14 14:22:55 +08:00
winger
af1a6a851f Merge remote-tracking branch 'upstream/master' 2018-09-14 14:07:02 +08:00
winger
1516cf779d 将当前的gtid,sequence no 和last committed信息增加至Entry(trx begin/end, rowdata) Header 中,客户端可从property中获取相关值 2018-09-14 14:06:32 +08:00
mcy
db56effd91 整理代码 2018-09-14 11:45:52 +08:00
mcy
f3d1c8b754 Merge branch 'master' of https://github.com/rewerma/canal 2018-09-14 11:24:27 +08:00
rewerma
abf6a37f3a Merge pull request #6 from alibaba/master
merge alibaba/canal
2018-09-14 11:24:09 +08:00
mcy
e8e0032404 增加扁平Message用于卡夫卡数据投递 2018-09-14 11:22:47 +08:00
agapple
52734eac7e Merge pull request #938 from WithLin/master
Fix upgrade proto2 to proto3
2018-09-13 18:53:10 +08:00
WithLin
ca61be5f5a fix upgrade proto2 to proto3 2018-09-13 18:37:26 +08:00
XiaoFu
b28e3d6f18 Merge pull request #2 from alibaba/master
pull request
2018-09-13 15:28:54 +08:00
agapple
1ab1f119b8 Merge pull request #931 from rewerma/master
fix #904: 空记录时sleep 1s防止循环get数据过快
2018-09-12 13:22:19 +08:00
agapple
a332f23b11 Merge pull request #919 from WithLin/master
Fix upgrade protobuf version
2018-09-12 13:20:40 +08:00
mcy
a6798c61df 空数据sleep 100ms 2018-09-12 09:03:43 +08:00
machey
8ae8f526a6 fix #904: 空记录时sleep 1s防止循环get数据过快 2018-09-11 22:47:53 +08:00
XiaoFu
847634a0f2 Merge pull request #1 from alibaba/master
pull a request
2018-09-11 17:13:48 +08:00
agapple
bc8f201b21 Merge pull request #927 from rewerma/master
fix #912 解决guava冲突问题
2018-09-11 12:31:24 +08:00
mcy
e450c3f83f fix #912 通过maven插件将guava修改包路径打包进canal.client 2018-09-11 11:35:47 +08:00
rewerma
32910b5983 Merge pull request #5 from alibaba/master
merge from alibaba/canal
2018-09-11 02:19:20 +08:00
WithLin
a497962153 Fix upgrade protobuf version 2018-09-07 14:27:19 +08:00
七锋
82f8a9fc98 fixed issue #483 , show slave hosts 2018-09-04 12:55:16 +08:00
七锋
f5bf1667a9 fixed mq and client launcher 2018-09-04 12:35:20 +08:00
七锋
a9cccb3017 fixed format 2018-09-04 11:39:23 +08:00
七锋
47ac10ca18 fixed issue #868 , NPE fixed 2018-09-04 11:28:56 +08:00
agapple
d4a70d5eea Merge pull request #900 from rewerma/master
kafka server端代码调整
2018-09-04 10:55:04 +08:00
agapple
e78de8568e Merge pull request #902 from wingerx/master
fix bug #890: 并行解析 + Gtid .没有初始化LogContext中的gtidSet
2018-09-04 10:53:07 +08:00
mcy
728550cac3 增加kafka producer send结果同步判断 2018-09-04 09:56:51 +08:00
mcy
81c216f1c1 增加kafka get的超时时间 2018-09-04 09:39:02 +08:00
mcy
17f345bfe5 0.11的环境未测过,先去除kafka的事务 2018-09-03 18:07:43 +08:00
mcy
ebf9139762 增加kafka producer sender的callback,canal和kafka同步提交回滚
去除一个canal实例对应多个kafka topic的机制,一个实例只对应一个topic
kafka模式下server端的批次大小不能超过1M,最大为900K
2018-09-03 17:40:30 +08:00
winger
7de40091a3 fix bug #890 2018-09-03 15:28:15 +08:00
machey
ee5775ce05 去掉kafka server端TRANSACTIONBEGIN和TRANSACTIONEND的判断 2018-09-02 20:21:07 +08:00
agapple
21ef2e5dd4 Merge pull request #896 from lcybo/master
修复execTime快于canal当前时间,delay无data points
2018-08-31 13:59:57 +08:00
agapple
283956ee93 Merge pull request #894 from zhangxin1988/master
fix #893 index name contains "on" keyword
2018-08-31 13:59:29 +08:00
Chuanyi Li
06275a46ed Fix no data points while execTime exceeding current time of canal server. 2018-08-29 19:52:09 +08:00
张鑫
ea81b1dc92 fix #893 index name contains "on" keyword 2018-08-29 14:37:27 +08:00
agapple
fd5cfe23db Merge pull request #892 from rewerma/master
kafka client keep alive间隔时间
2018-08-28 17:47:31 +08:00
mcy
bcf30a9a05 去掉kafka canalBatchSize使用默认50 2018-08-28 15:52:36 +08:00
mcy
d5122dcf50 Merge branch 'master' of https://github.com/alibaba/canal 2018-08-28 15:49:27 +08:00
mcy
b5e05c8c77 kafka client keep alive间隔时间 2018-08-28 13:51:23 +08:00
agapple
9434ed513e Merge pull request #881 from wingerx/master
fix bug: 并行解析模式下,开启gtid 会导致解析错误
2018-08-26 22:00:59 +08:00
winger
6fe3ef43d8 fix bug: 并行解析模式下,开启gtid 会导致解析错误 2018-08-25 09:17:13 +08:00
winger
c1f92858a2 fix bug: 并行解析模式下,开启gtid 会导致解析错误 2018-08-25 03:54:38 +08:00
agapple
00b5ade787 Merge pull request #876 from rewerma/master
整合 kafka 到 server 和 client
2018-08-24 12:05:07 +08:00
mcy
6b94f396ff 移除kafka client基于zk的HA机制 2018-08-24 10:52:04 +08:00
mcy
b7de1e5070 删除kafka kafka-client模块 2018-08-24 09:14:52 +08:00
machey
4fe6c36c49 Merge branch 'develop-tmp'
# Conflicts:
#	kafka-client/pom.xml
#	kafka/pom.xml
2018-08-23 23:59:20 +08:00
agapple
899592ce2a Merge pull request #873 from lcybo/master
单核环境下创建线程池会出错。
2018-08-23 19:17:47 +08:00
Chuanyi Li L
8585761f42 Merge branch 'master' of https://github.com/lcybo/canal 2018-08-23 17:52:23 +08:00
Chuanyi Li L
1aa2e1a409 Ensure at least 1 thread for thread pool. 2018-08-23 17:51:25 +08:00
mcy
9e3d4a7ffe HBase读配置空行的bug 2018-08-23 17:43:53 +08:00
mcy
fc3de4b7fd 整合canal.client和canal.kafka-client 2018-08-23 17:38:17 +08:00
mcy
e7f07d7d3e 整合canal.server和canal.kafka 2018-08-23 17:33:15 +08:00
七锋
6e07021223 fixed client version 1.1.1-SNAPSHOT 2018-08-23 14:27:16 +08:00
agapple
3c80b6c1f7 Merge pull request #865 from rewerma/master
fix #849: HBase数据同步适配
2018-08-23 13:58:23 +08:00
mcy
20b0b39b14 fix #849: hbase数据同步适配 2018-08-23 12:02:44 +08:00
lcybo
de59d22429 Merge pull request #861 from Lee-Think/master
Client QPS指标的datasource配置项由"Prometheus"改为取$datasource参数
2018-08-21 18:59:36 +08:00
lixiang
1bef1b72bc Client QPS指标的datasource配置项由"Prometheus"改为取$datasource参数 2018-08-21 17:20:00 +08:00
mcy
47348e2e96 新增client-launcher模块,外部数据落地适配器的总入口 2018-08-20 18:22:11 +08:00
七锋
0f3c427e28 fixed docker run 2018-08-20 14:28:12 +08:00
七锋
9bde69b6d6 [maven-release-plugin] prepare for next development iteration 2018-08-20 13:29:12 +08:00
1172 changed files with 89223 additions and 19769 deletions

6
.codecov.yml Normal file
View File

@@ -0,0 +1,6 @@
coverage:
status:
# pull-requests only
patch:
default:
threshold: 0.1%

View File

@@ -0,0 +1,8 @@
---
name: Any Questions on Canal
about: Ask whatever you want to know or confusion about Canal
---
## Question
<!-- You can ask any question about this project -->

View File

@@ -0,0 +1,29 @@
---
name: Bug Report for Canal
about: Create a report to help us improve
---
- [ ] I have searched the [issues](https://github.com/alibaba/canal/issues) of this repository and believe that this is not a duplicate.
- [ ] I have checked the [FAQ](https://github.com/alibaba/canal/wiki/FAQ) of this repository and believe that this is not a duplicate.
### environment
* canal version
* mysql version
### Issue Description
### Steps to reproduce
### Expected behaviour
### Actual behaviour
If there is an exception, please attach the exception trace:
```
Just put your stack trace here!
```

View File

@@ -0,0 +1,16 @@
---
name: Feature Request of Canal
about: Suggest an idea for this project
---
## Why you need it?
<!-- Is your feature request related to a problem? Please describe in details -->
## How it could be?
<!--A clear and concise description of what you want to happen. For a computer fan, you can explain more about input of the feature, and output of it.-->
## Other related information
<!-- Add any other context or screenshots about the feature request here.-->

7
.gitignore vendored
View File

@@ -16,3 +16,10 @@ jtester.properties
.DS_Store
*.tar.gz
*.rpm
client-adapter/example/
*.dat
conf/
canal-admin/canal-admin-ui/dist/
canal-admin/canal-admin-ui/node/
canal-admin/canal-admin-ui/node_modules/
canal-admin/canal-admin-server/src/main/resources/conf/

BIN
.mvn/wrapper/maven-wrapper.jar vendored Executable file

Binary file not shown.

1
.mvn/wrapper/maven-wrapper.properties vendored Executable file
View File

@@ -0,0 +1 @@
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip

23
.travis.yml Normal file
View File

@@ -0,0 +1,23 @@
language: java
sudo: false # faster builds
jdk:
- oraclejdk12
- openjdk11
- oraclejdk11
- openjdk8
cache:
directories:
- $HOME/.m2
install: true
script:
- travis_wait 30 ./mvnw -T 1C clean install -DskipTests=false -Dcheckstyle.skip=true -Dmaven.javadoc.skip=true
after_success:
- bash <(curl -s https://codecov.io/bash)
after_failure:
- if [ -f canal.log ]; then echo "------TAIL of canal.log------"; tail -n 1000 canal.log; echo "------END of canal.log------"; fi

188
README.md
View File

@@ -1,99 +1,111 @@
<div class="blog_content">
<div class="iteye-blog-content-contain">
[![build status](https://travis-ci.com/alibaba/canal.svg?branch=master)](https://travis-ci.com/alibaba/canal)
[![codecov](https://codecov.io/gh/alibaba/canal/branch/master/graph/badge.svg)](https://codecov.io/gh/alibaba/canal)
![maven](https://img.shields.io/maven-central/v/com.alibaba.otter/canal.svg)
![license](https://img.shields.io/github/license/alibaba/canal.svg)
[![average time to resolve an issue](http://isitmaintained.com/badge/resolution/alibaba/canal.svg)](http://isitmaintained.com/project/alibaba/canal "average time to resolve an issue")
[![percentage of issues still open](http://isitmaintained.com/badge/open/alibaba/canal.svg)](http://isitmaintained.com/project/alibaba/canal "percentage of issues still open")
[![Leaderboard](https://img.shields.io/badge/Canal-%E6%9F%A5%E7%9C%8B%E8%B4%A1%E7%8C%AE%E6%8E%92%E8%A1%8C%E6%A6%9C-orange)](https://opensource.alibaba.com/contribution_leaderboard/details?projectValue=canal)
<h3>最新更新</h3>
<ol>
<li>canal QQ讨论群已经建立,群号:161559791 ,欢迎加入进行技术讨论。</li>
<li>canal消费端项目开源: Otter(分布式数据库同步系统),地址:<a href="https://github.com/alibaba/otter">https://github.com/alibaba/otter</a></li>
<li>Canal已在阿里云推出商业化版本 <a href="https://www.aliyun.com/product/dts?spm=a2c4g.11186623.cloudEssentials.80.srdwr7">数据传输服务DTS</a>, 开通即用,免去部署维护的昂贵使用成本。DTS针对阿里云RDS、DRDS等产品进行了适配,解决了Binlog日志回收,主备切换、VPC网络切换等场景下的订阅高可用问题。同时,针对RDS进行了针对性的性能优化。出于稳定性、性能及成本的考虑,强烈推荐阿里云用户使用DTS产品。<a href="https://help.aliyun.com/document_detail/26592.html?spm=a2c4g.11174283.6.539.t1Y91E">DTS产品使用文档</a></li>
DTS支持阿里云RDS&DRDS的Binlog日志实时订阅,现推出首月免费体验,限时限量,<a href="https://common-buy.aliyun.com/?commodityCode=dtspre&request=%7b%22dts_function%22%3a%22data_subscribe%22%7d">立即体验>>></a>
</ol>
<h1>背景</h1>
<p style="font-size: 14px;"> 早期,阿里巴巴B2B公司因为存在杭州和美国双机房部署,存在跨机房同步的业务需求。不过早期的数据库同步业务,主要是基于trigger的方式获取增量变更,不过从2010年开始,阿里系公司开始逐步的尝试基于数据库的日志解析,获取增量变更进行同步,由此衍生出了增量订阅&amp;消费的业务,从此开启了一段新纪元。</p>
<p style="font-size: 14px;"> ps. 目前内部版本已经支持mysql和oracle部分版本的日志解析,当前的canal开源版本支持5.7及以下的版本(阿里内部mysql 5.7.13, 5.6.10, mysql 5.5.18和5.1.40/48)</p>
<p style="font-size: 14px;"> </p>
<p style="font-size: 14px;">基于日志增量订阅&amp;消费支持的业务:</p>
<ol style="font-size: 14px;">
<li>数据库镜像</li>
<li>数据库实时备份</li>
<li>多级索引 (卖家和买家各自分库索引)</li>
<li>search build</li>
<li>业务cache刷新</li>
<li>价格变化等重要业务消息</li>
</ol>
<h1>项目介绍</h1>
<p style="font-size: 14px;"> 名称:canal [kə'næl]</p>
<p style="font-size: 14px;"> 译意: 水道/管道/沟渠 </p>
<p style="font-size: 14px;"> 语言: 纯java开发</p>
<p style="font-size: 14px;"> 定位: 基于数据库增量日志解析,提供增量数据订阅&amp;消费,目前主要支持了mysql</p>
<p style="font-size: 14px;"> 关键词: mysql binlog parser / real-time / queue&topic </p>
<p style="font-size: 14px;"> </p>
<h2>工作原理</h2>
<h3 style="font-size: 14px;">mysql主备复制实现</h3>
<p><img src="http://dl.iteye.com/upload/attachment/0080/3086/468c1a14-e7ad-3290-9d3d-44ac501a7227.jpg" alt=""><br> 从上层来看,复制分成三步:
<ol>
<li>master将改变记录到二进制日志(binary log)中(这些记录叫做二进制日志事件,binary log events,可以通过show binlog events进行查看);</li>
<li>slave将master的binary log events拷贝到它的中继日志(relay log);</li>
<li>slave重做中继日志中的事件,将改变反映它自己的数据。</li>
</ol>
<h3>canal的工作原理:</h3>
<p><img width="590" src="http://dl.iteye.com/upload/attachment/0080/3107/c87b67ba-394c-3086-9577-9db05be04c95.jpg" alt="" height="273">
<p>原理相对比较简单:</p>
<ol>
<li>canal模拟mysql slave的交互协议,伪装自己为mysql slave,向mysql master发送dump协议</li>
<li>mysql master收到dump请求,开始推送binary log给slave(也就是canal)</li>
<li>canal解析binary log对象(原始为byte流)</li>
</ol>
## 简介
<h1>相关文档</h1>
![](https://img-blog.csdnimg.cn/20191104101735947.png)
See the wiki page for : <a href="https://github.com/alibaba/canal/wiki" >wiki文档</a>
**canal [kə'næl]**,译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费
<h3><a name="table-of-contents" class="anchor" href="#table-of-contents"><span class="mini-icon mini-icon-link"></span></a>wiki文档列表</h3>
<ul>
<li><a class="internal present" href="https://github.com/alibaba/canal/wiki/Home">Home</a></li>
<li><a class="internal present" href="https://github.com/alibaba/canal/wiki/Introduction">Introduction</a></li>
<li><a class="internal present" href="https://github.com/alibaba/canal/wiki/QuickStart">QuickStart</a></li>
<li><a class="internal present" href="https://github.com/alibaba/canal/wiki/ClientExample">ClientExample</a></li>
<li><a class="internal present" href="https://github.com/alibaba/canal/wiki/AdminGuide">AdminGuide</a></li>
<li><a class="internal present" href="https://github.com/alibaba/canal/wiki/ClientAPI">ClientAPI</a></li>
<li><a class="internal present" href="https://github.com/alibaba/canal/wiki/DevGuide">DevGuide</a></li>
<li><a class="internal present" href="https://github.com/alibaba/canal/wiki/BinlogChange%28mysql5.6%29">BinlogChange(Mysql5.6)</a></li>
<li><a href="http://alibaba.github.com/canal/release.html">ReleaseNotes</a></li>
<li><a href="https://github.com/alibaba/canal/releases">Download</a></li>
</ul>
早期阿里巴巴因为杭州和美国双机房部署,存在跨机房同步的业务需求,实现方式主要是基于业务 trigger 获取增量变更。从 2010 年开始,业务逐步尝试数据库日志解析获取增量变更进行同步,由此衍生出了大量的数据库增量订阅和消费业务。
<h1>相关资料</h1>
基于日志增量订阅和消费的业务包括
- 数据库镜像
- 数据库实时备份
- 索引构建和实时维护(拆分异构索引、倒排索引等)
- 业务 cache 刷新
- 带业务逻辑的增量数据处理
* ADC阿里技术嘉年华分享ppt (放在google docs上,可能需要翻墙): <a href="https://docs.google.com/presentation/d/1MkszUPYRDkfVPz9IqOT1LLT5d9tuwde_WC8GZvjaDRg/edit?usp=sharing">ppt下载</href>
* [与阿里巴巴的RocketMQ配合使用](https://github.com/alibaba/RocketMQ)
当前的 canal 支持源端 MySQL 版本包括 5.1.x , 5.5.x , 5.6.x , 5.7.x , 8.0.x
<h1>相关开源</h1>
<ol>
<li>阿里巴巴分布式数据库同步系统(解决中美异地机房):<a href="http://github.com/alibaba/otter">http://github.com/alibaba/otter</a></li>
<li>阿里巴巴去Oracle数据迁移同步工具(目标支持MySQL/DRDS):<a href="http://github.com/alibaba/yugong">http://github.com/alibaba/yugong</a></li>
</ol>
## 工作原理
<h1>相关产品</h1>
<ol>
<li><a href="https://www.aliyun.com/product/drds?spm=5176.55326.cloudEssentials.71.69fd227dRPZj9K">阿里云分布式数据库DRDS</a></li>
<li><a href="https://www.aliyun.com/product/dts?spm=5176.7947010.cloudEssentials.80.33f734f4JOAxSP">阿里云数据传输服务DTS</a></li>
<li><a href="https://www.aliyun.com/product/dbs?spm=5176.54487.cloudEssentials.83.34b851a8GmVZg6">阿里云数据库备份服务DBS</a></li>
<li><a href="https://www.aliyun.com/product/dms?spm=5176.169464.cloudEssentials.81.2e1066feC1sBBL">阿里云数据管理服务DMS</a></li>
</ol>
#### MySQL主备复制原理
![](http://dl.iteye.com/upload/attachment/0080/3086/468c1a14-e7ad-3290-9d3d-44ac501a7227.jpg)
<h1>问题反馈</h1>
<ol>
<li>qq交流群: 161559791 </li>
<li>邮件交流: jianghang115@gmail.com </li>
<li>新浪微博: agapple0002 </li>
<li>报告issue:<a href="https://github.com/alibaba/canal/issues">issues</a></li>
</ol>
- MySQL master 将数据变更写入二进制日志( binary log, 其中记录叫做二进制日志事件binary log events,可以通过 show binlog events 进行查看)
- MySQL slave 将 master 的 binary log events 拷贝到它的中继日志(relay log)
- MySQL slave 重放 relay log 中事件,将数据变更反映它自己的数据
<pre>
【招聘】阿里巴巴中间件团队招聘JAVA高级工程师
岗位主要为技术型内容(非业务部门),阿里中间件整个体系对于未来想在技术上有所沉淀的同学还是非常有帮助的
工作地点:杭州、北京均可. ps. 阿里待遇向来都是不错的,有意者可以QQ、微博私聊.
具体招聘内容:https://job.alibaba.com/zhaopin/position_detail.htm?positionId=32666
</pre>
#### canal 工作原理
- canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave ,向 MySQL master 发送dump 协议
- MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal )
- canal 解析 binary log 对象(原始为 byte 流)
## 重要版本更新说明
1. canal 1.1.x 版本([release_note](https://github.com/alibaba/canal/releases)),性能与功能层面有较大的突破,重要提升包括:
- 整体性能测试&优化,提升了150%. #726 参考: [Performance](https://github.com/alibaba/canal/wiki/Performance)
- 原生支持prometheus监控 #765 [Prometheus QuickStart](https://github.com/alibaba/canal/wiki/Prometheus-QuickStart)
- 原生支持kafka消息投递 #695 [Canal Kafka/RocketMQ QuickStart](https://github.com/alibaba/canal/wiki/Canal-Kafka-RocketMQ-QuickStart)
- 原生支持aliyun rds的binlog订阅 (解决自动主备切换/oss binlog离线解析) 参考: [Aliyun RDS QuickStart](https://github.com/alibaba/canal/wiki/aliyun-RDS-QuickStart)
- 原生支持docker镜像 #801 参考: [Docker QuickStart](https://github.com/alibaba/canal/wiki/Docker-QuickStart)
2. canal 1.1.4版本,迎来最重要的WebUI能力,引入canal-admin工程,支持面向WebUI的canal动态管理能力,支持配置、任务、日志等在线白屏运维能力,具体文档:[Canal Admin Guide](https://github.com/alibaba/canal/wiki/Canal-Admin-Guide)
## 文档
- [Home](https://github.com/alibaba/canal/wiki/Home)
- [Introduction](https://github.com/alibaba/canal/wiki/Introduction)
- [QuickStart](https://github.com/alibaba/canal/wiki/QuickStart)
- [Docker QuickStart](https://github.com/alibaba/canal/wiki/Docker-QuickStart)
- [Canal Kafka/RocketMQ QuickStart](https://github.com/alibaba/canal/wiki/Canal-Kafka-RocketMQ-QuickStart")
- [Aliyun RDS for MySQL QuickStart](https://github.com/alibaba/canal/wiki/aliyun-RDS-QuickStart)
- [Prometheus QuickStart](https://github.com/alibaba/canal/wiki/Prometheus-QuickStart)
- Canal Admin
- [Canal Admin QuickStart](https://github.com/alibaba/canal/wiki/Canal-Admin-QuickStart)
- [Canal Admin Guide](https://github.com/alibaba/canal/wiki/Canal-Admin-Guide)
- [Canal Admin ServerGuide](https://github.com/alibaba/canal/wiki/Canal-Admin-ServerGuide)
- [Canal Admin Docker](https://github.com/alibaba/canal/wiki/Canal-Admin-Docker)
- [AdminGuide](https://github.com/alibaba/canal/wiki/AdminGuide)
- [ClientExample](https://github.com/alibaba/canal/wiki/ClientExample)
- [ClientAPI](https://github.com/alibaba/canal/wiki/ClientAPI)
- [Performance](https://github.com/alibaba/canal/wiki/Performance)
- [DevGuide](https://github.com/alibaba/canal/wiki/DevGuide)
- [BinlogChange(MySQL 5.6)](https://github.com/alibaba/canal/wiki/BinlogChange%28mysql5.6%29)
- [BinlogChange(MariaDB)](https://github.com/alibaba/canal/wiki/BinlogChange%28MariaDB%29)
- [TableMetaTSDB](https://github.com/alibaba/canal/wiki/TableMetaTSDB)
- [ReleaseNotes](http://alibaba.github.com/canal/release.html)
- [Download](https://github.com/alibaba/canal/releases)
- [FAQ](https://github.com/alibaba/canal/wiki/FAQ)
## 多语言
canal 特别设计了 client-server 模式,交互协议使用 protobuf 3.0 , client 端可采用不同语言实现不同的消费逻辑,欢迎大家提交 pull request
- canal java 客户端: [https://github.com/alibaba/canal/wiki/ClientExample](https://github.com/alibaba/canal/wiki/ClientExample)
- canal c# 客户端: [https://github.com/dotnetcore/CanalSharp](https://github.com/dotnetcore/CanalSharp)
- canal go客户端: [https://github.com/CanalClient/canal-go](https://github.com/CanalClient/canal-go)
- canal php客户端: [https://github.com/xingwenge/canal-php](https://github.com/xingwenge/canal-php)
- canal Python客户端:[https://github.com/haozi3156666/canal-python](https://github.com/haozi3156666/canal-python)
- canal Rust客户端:[https://github.com/laohanlinux/canal-rs](https://github.com/laohanlinux/canal-rs)
- canal Nodejs客户端:[https://github.com/marmot-z/canal-nodejs](https://github.com/marmot-z/canal-nodejs)
canal 作为 MySQL binlog 增量获取和解析工具,可将变更记录投递到 MQ 系统中,比如 Kafka/RocketMQ,可以借助于 MQ 的多语言能力
- 参考文档: [Canal Kafka/RocketMQ QuickStart](https://github.com/alibaba/canal/wiki/Canal-Kafka-RocketMQ-QuickStart)
## 基于canal开发的工具
- canal2sql(基于binlog生成SQL) : [https://github.com/zhuchao941/canal2sql]
## 相关开源&产品
- [canal 消费端开源项目: Otter](http://github.com/alibaba/otter)
- [阿里巴巴去 Oracle 数据迁移同步工具: yugong](http://github.com/alibaba/yugong)
- [阿里巴巴离线同步开源项目 DataX](https://github.com/alibaba/datax)
- [阿里巴巴数据库连接池开源项目 Druid](https://github.com/alibaba/druid)
- [阿里巴巴实时数据同步工具 DTS](https://www.aliyun.com/product/dts)
## 问题反馈
- 报告 issue: [github issues](https://github.com/alibaba/canal/issues)
本项目的Issues会被同步沉淀至[阿里云开发者社区](https://developer.aliyun.com/ask)

View File

@@ -0,0 +1,14 @@
# http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
insert_final_newline = false
trim_trailing_whitespace = false

View File

@@ -0,0 +1,14 @@
# just a flag
ENV = 'development'
# base api
VUE_APP_BASE_API = 'http://127.0.0.1:8089/api/v1'
# vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable,
# to control whether the babel-plugin-dynamic-import-node plugin is enabled.
# It only does one thing by converting all import() to require().
# This configuration can significantly increase the speed of hot updates,
# when you have a large number of pages.
# Detail: https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/babel-preset-app/index.js
VUE_CLI_BABEL_TRANSPILE_MODULES = true

View File

@@ -0,0 +1,6 @@
# just a flag
ENV = 'production'
# base api
VUE_APP_BASE_API = '/api/v1'

View File

@@ -0,0 +1,8 @@
NODE_ENV = production
# just a flag
ENV = 'staging'
# base api
VUE_APP_BASE_API = '/stage-api'

View File

@@ -0,0 +1,4 @@
build/*.js
src/assets
public
dist

198
admin/admin-ui/.eslintrc.js Normal file
View File

@@ -0,0 +1,198 @@
module.exports = {
root: true,
parserOptions: {
parser: 'babel-eslint',
sourceType: 'module'
},
env: {
browser: true,
node: true,
es6: true,
},
extends: ['plugin:vue/recommended', 'eslint:recommended'],
// add your custom rules here
//it is base on https://github.com/vuejs/eslint-config-vue
rules: {
"vue/max-attributes-per-line": [2, {
"singleline": 10,
"multiline": {
"max": 1,
"allowFirstLine": false
}
}],
"vue/singleline-html-element-content-newline": "off",
"vue/multiline-html-element-content-newline":"off",
"vue/name-property-casing": ["error", "PascalCase"],
"vue/no-v-html": "off",
'accessor-pairs': 2,
'arrow-spacing': [2, {
'before': true,
'after': true
}],
'block-spacing': [2, 'always'],
'brace-style': [2, '1tbs', {
'allowSingleLine': true
}],
'camelcase': [0, {
'properties': 'always'
}],
'comma-dangle': [2, 'never'],
'comma-spacing': [2, {
'before': false,
'after': true
}],
'comma-style': [2, 'last'],
'constructor-super': 2,
'curly': [2, 'multi-line'],
'dot-location': [2, 'property'],
'eol-last': 2,
'eqeqeq': ["error", "always", {"null": "ignore"}],
'generator-star-spacing': [2, {
'before': true,
'after': true
}],
'handle-callback-err': [2, '^(err|error)$'],
'indent': [2, 2, {
'SwitchCase': 1
}],
'jsx-quotes': [2, 'prefer-single'],
'key-spacing': [2, {
'beforeColon': false,
'afterColon': true
}],
'keyword-spacing': [2, {
'before': true,
'after': true
}],
'new-cap': [2, {
'newIsCap': true,
'capIsNew': false
}],
'new-parens': 2,
'no-array-constructor': 2,
'no-caller': 2,
'no-console': 'off',
'no-class-assign': 2,
'no-cond-assign': 2,
'no-const-assign': 2,
'no-control-regex': 0,
'no-delete-var': 2,
'no-dupe-args': 2,
'no-dupe-class-members': 2,
'no-dupe-keys': 2,
'no-duplicate-case': 2,
'no-empty-character-class': 2,
'no-empty-pattern': 2,
'no-eval': 2,
'no-ex-assign': 2,
'no-extend-native': 2,
'no-extra-bind': 2,
'no-extra-boolean-cast': 2,
'no-extra-parens': [2, 'functions'],
'no-fallthrough': 2,
'no-floating-decimal': 2,
'no-func-assign': 2,
'no-implied-eval': 2,
'no-inner-declarations': [2, 'functions'],
'no-invalid-regexp': 2,
'no-irregular-whitespace': 2,
'no-iterator': 2,
'no-label-var': 2,
'no-labels': [2, {
'allowLoop': false,
'allowSwitch': false
}],
'no-lone-blocks': 2,
'no-mixed-spaces-and-tabs': 2,
'no-multi-spaces': 2,
'no-multi-str': 2,
'no-multiple-empty-lines': [2, {
'max': 1
}],
'no-native-reassign': 2,
'no-negated-in-lhs': 2,
'no-new-object': 2,
'no-new-require': 2,
'no-new-symbol': 2,
'no-new-wrappers': 2,
'no-obj-calls': 2,
'no-octal': 2,
'no-octal-escape': 2,
'no-path-concat': 2,
'no-proto': 2,
'no-redeclare': 2,
'no-regex-spaces': 2,
'no-return-assign': [2, 'except-parens'],
'no-self-assign': 2,
'no-self-compare': 2,
'no-sequences': 2,
'no-shadow-restricted-names': 2,
'no-spaced-func': 2,
'no-sparse-arrays': 2,
'no-this-before-super': 2,
'no-throw-literal': 2,
'no-trailing-spaces': 2,
'no-undef': 2,
'no-undef-init': 2,
'no-unexpected-multiline': 2,
'no-unmodified-loop-condition': 2,
'no-unneeded-ternary': [2, {
'defaultAssignment': false
}],
'no-unreachable': 2,
'no-unsafe-finally': 2,
'no-unused-vars': [2, {
'vars': 'all',
'args': 'none'
}],
'no-useless-call': 2,
'no-useless-computed-key': 2,
'no-useless-constructor': 2,
'no-useless-escape': 0,
'no-whitespace-before-property': 2,
'no-with': 2,
'one-var': [2, {
'initialized': 'never'
}],
'operator-linebreak': [2, 'after', {
'overrides': {
'?': 'before',
':': 'before'
}
}],
'padded-blocks': [2, 'never'],
'quotes': [2, 'single', {
'avoidEscape': true,
'allowTemplateLiterals': true
}],
'semi': [2, 'never'],
'semi-spacing': [2, {
'before': false,
'after': true
}],
'space-before-blocks': [2, 'always'],
'space-before-function-paren': [2, 'never'],
'space-in-parens': [2, 'never'],
'space-infix-ops': 2,
'space-unary-ops': [2, {
'words': true,
'nonwords': false
}],
'spaced-comment': [2, 'always', {
'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ',']
}],
'template-curly-spacing': [2, 'never'],
'use-isnan': 2,
'valid-typeof': 2,
'wrap-iife': [2, 'any'],
'yield-star-spacing': [2, 'both'],
'yoda': [2, 'never'],
'prefer-const': 2,
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
'object-curly-spacing': [2, 'always', {
objectsInObjects: false
}],
'array-bracket-spacing': [2, 'never']
}
}

17
admin/admin-ui/.gitignore vendored Normal file
View File

@@ -0,0 +1,17 @@
.DS_Store
node_modules/
dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
package-lock.json
tests/**/coverage/
target/
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln

View File

@@ -0,0 +1,5 @@
language: node_js
node_js: 10
script: npm run test
notifications:
email: false

21
admin/admin-ui/LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017-present PanJiaChen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/app'
]
}

View File

@@ -0,0 +1,35 @@
const { run } = require('runjs')
const chalk = require('chalk')
const config = require('../vue.config.js')
const rawArgv = process.argv.slice(2)
const args = rawArgv.join(' ')
if (process.env.npm_config_preview || rawArgv.includes('--preview')) {
const report = rawArgv.includes('--report')
run(`vue-cli-service build ${args}`)
const port = 9526
const publicPath = config.publicPath
var connect = require('connect')
var serveStatic = require('serve-static')
const app = connect()
app.use(
publicPath,
serveStatic('./target/dist', {
index: ['index.html', '/']
})
)
app.listen(port, function () {
console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`))
if (report) {
console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}report.html`))
}
})
} else {
run(`vue-cli-service build ${args}`)
}

View File

@@ -0,0 +1,24 @@
module.exports = {
moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
transform: {
'^.+\\.vue$': 'vue-jest',
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':
'jest-transform-stub',
'^.+\\.jsx?$': 'babel-jest'
},
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1'
},
snapshotSerializers: ['jest-serializer-vue'],
testMatch: [
'**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
],
collectCoverageFrom: ['src/utils/**/*.{js,vue}', '!src/utils/auth.js', '!src/utils/request.js', 'src/components/**/*.{js,vue}'],
coverageDirectory: '<rootDir>/tests/unit/coverage',
// 'collectCoverage': true,
'coverageReporters': [
'lcov',
'text-summary'
],
testURL: 'http://localhost/'
}

View File

@@ -0,0 +1,66 @@
import Mock from 'mockjs'
import { param2Obj } from '../src/utils'
import user from './user'
import table from './table'
const mocks = [
...user,
...table
]
// for front mock
// please use it cautiously, it will redefine XMLHttpRequest,
// which will cause many of your third-party libraries to be invalidated(like progress event).
export function mockXHR() {
// mock patch
// https://github.com/nuysoft/Mock/issues/300
Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
Mock.XHR.prototype.send = function() {
if (this.custom.xhr) {
this.custom.xhr.withCredentials = this.withCredentials || false
if (this.responseType) {
this.custom.xhr.responseType = this.responseType
}
}
this.proxy_send(...arguments)
}
function XHR2ExpressReqWrap(respond) {
return function(options) {
let result = null
if (respond instanceof Function) {
const { body, type, url } = options
// https://expressjs.com/en/4x/api.html#req
result = respond({
method: type,
body: JSON.parse(body),
query: param2Obj(url)
})
} else {
result = respond
}
return Mock.mock(result)
}
}
for (const i of mocks) {
Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response))
}
}
// for mock server
const responseFake = (url, type, respond) => {
return {
url: new RegExp(`/mock${url}`),
type: type || 'get',
response(req, res) {
res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))
}
}
}
export default mocks.map(route => {
return responseFake(route.url, route.type, route.response)
})

View File

@@ -0,0 +1,68 @@
const chokidar = require('chokidar')
const bodyParser = require('body-parser')
const chalk = require('chalk')
const path = require('path')
const mockDir = path.join(process.cwd(), 'mock')
function registerRoutes(app) {
let mockLastIndex
const { default: mocks } = require('./index.js')
for (const mock of mocks) {
app[mock.type](mock.url, mock.response)
mockLastIndex = app._router.stack.length
}
const mockRoutesLength = Object.keys(mocks).length
return {
mockRoutesLength: mockRoutesLength,
mockStartIndex: mockLastIndex - mockRoutesLength
}
}
function unregisterRoutes() {
Object.keys(require.cache).forEach(i => {
if (i.includes(mockDir)) {
delete require.cache[require.resolve(i)]
}
})
}
module.exports = app => {
// es6 polyfill
require('@babel/register')
// parse app.body
// https://expressjs.com/en/4x/api.html#req.body
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
extended: true
}))
const mockRoutes = registerRoutes(app)
var mockRoutesLength = mockRoutes.mockRoutesLength
var mockStartIndex = mockRoutes.mockStartIndex
// watch files, hot reload mock server
chokidar.watch(mockDir, {
ignored: /mock-server/,
ignoreInitial: true
}).on('all', (event, path) => {
if (event === 'change' || event === 'add') {
try {
// remove mock routes stack
app._router.stack.splice(mockStartIndex, mockRoutesLength)
// clear routes cache
unregisterRoutes()
const mockRoutes = registerRoutes(app)
mockRoutesLength = mockRoutes.mockRoutesLength
mockStartIndex = mockRoutes.mockStartIndex
console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed ${path}`))
} catch (error) {
console.log(chalk.redBright(error))
}
}
})
}

View File

@@ -0,0 +1,29 @@
import Mock from 'mockjs'
const data = Mock.mock({
'items|30': [{
id: '@id',
title: '@sentence(10, 20)',
'status|1': ['published', 'draft', 'deleted'],
author: 'name',
display_time: '@datetime',
pageviews: '@integer(300, 5000)'
}]
})
export default [
{
url: '/table/list',
type: 'get',
response: config => {
const items = data.items
return {
code: 20000,
data: {
total: items.length,
items: items
}
}
}
}
]

View File

@@ -0,0 +1,84 @@
const tokens = {
admin: {
token: 'admin-token'
},
editor: {
token: 'editor-token'
}
}
const users = {
'admin-token': {
roles: ['admin'],
introduction: 'I am a super administrator',
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
name: 'Super Admin'
},
'editor-token': {
roles: ['editor'],
introduction: 'I am an editor',
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
name: 'Normal Editor'
}
}
export default [
// user login
{
url: '/user/login',
type: 'post',
response: config => {
const { username } = config.body
const token = tokens[username]
// mock error
if (!token) {
return {
code: 60204,
message: 'Account and password are incorrect.'
}
}
return {
code: 20000,
data: token
}
}
},
// get user info
{
url: '/user/info\.*',
type: 'get',
response: config => {
const { token } = config.query
const info = users[token]
// mock error
if (!info) {
return {
code: 50008,
message: 'Login failed, unable to get user details.'
}
}
return {
code: 20000,
data: info
}
}
},
// user logout
{
url: '/user/logout',
type: 'post',
response: _ => {
return {
code: 20000,
data: 'success'
}
}
}
]

BIN
admin/admin-ui/node/node Executable file

Binary file not shown.

View File

@@ -0,0 +1,65 @@
{
"name": "canal-admin-ui",
"version": "1.1.4",
"description": "A canal-admin ui with Element UI & axios & iconfont & permission control & lint",
"author": "Machengyuan <rewerma@163.com>",
"license": "MIT",
"scripts": {
"dev": "vue-cli-service serve",
"build": "vue-cli-service build",
"build:stage": "vue-cli-service build --mode staging",
"preview": "node build/index.js --preview",
"lint": "eslint --ext .js,.vue src",
"test:unit": "jest --clearCache && vue-cli-service test:unit",
"test:ci": "npm run lint && npm run test:unit",
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml"
},
"dependencies": {
"axios": "0.18.1",
"element-ui": "2.7.2",
"js-cookie": "2.2.0",
"normalize.css": "7.0.0",
"nprogress": "0.2.0",
"path-to-regexp": "2.4.0",
"vue": "2.6.10",
"vue-router": "3.0.6",
"vuex": "3.1.0"
},
"devDependencies": {
"@babel/core": "7.0.0",
"@babel/register": "7.0.0",
"@vue/cli-plugin-babel": "3.6.0",
"@vue/cli-plugin-eslint": "^3.9.1",
"@vue/cli-plugin-unit-jest": "3.6.3",
"@vue/cli-service": "3.6.0",
"@vue/test-utils": "1.0.0-beta.29",
"autoprefixer": "^9.5.1",
"babel-core": "7.0.0-bridge.0",
"babel-eslint": "10.0.1",
"babel-jest": "23.6.0",
"chalk": "2.4.2",
"connect": "3.6.6",
"eslint": "5.15.3",
"eslint-plugin-vue": "5.2.2",
"html-webpack-plugin": "3.2.0",
"mockjs": "1.0.1-beta3",
"node-sass": "^4.9.0",
"runjs": "^4.3.2",
"sass-loader": "^7.1.0",
"script-ext-html-webpack-plugin": "2.1.3",
"script-loader": "0.7.2",
"serve-static": "^1.13.2",
"svg-sprite-loader": "4.1.3",
"svgo": "1.2.2",
"vue-template-compiler": "2.6.10",
"vue2-ace-editor": "^0.0.13"
},
"engines": {
"node": ">=8.9",
"npm": ">= 3.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions"
]
}

73
admin/admin-ui/pom.xml Normal file
View File

@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>canal.admin</artifactId>
<groupId>com.alibaba.otter</groupId>
<version>1.1.8-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>canal.admin-ui</artifactId>
<name>canal admin-ui module for otter ${project.version}</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<frontend-maven-plugin.version>1.6</frontend-maven-plugin.version>
</properties>
<profiles>
<profile>
<id>npm</id>
<activation>
<property>
<name>env</name>
<value>npm</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>${frontend-maven-plugin.version}</version>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<configuration>
<nodeVersion>v9.11.1</nodeVersion>
</configuration>
</execution>
<!-- Install all project dependencies -->
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
<!-- optional: default phase is "generate-resources" -->
<phase>generate-resources</phase>
<!-- Optional configuration which provides for running any npm command -->
<configuration>
<arguments>install</arguments>
</configuration>
</execution>
<!-- Build and minify static files -->
<execution>
<id>npm run build</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>run build</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -0,0 +1,8 @@
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
'plugins': {
// to edit target browsers: use "browserslist" field in package.json
'autoprefixer': {}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= webpackConfig.name %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= webpackConfig.name %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -0,0 +1,11 @@
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
export default {
name: 'App'
}
</script>

View File

@@ -0,0 +1,46 @@
import request from '@/utils/request'
export function getCanalClusters(params) {
return request({
url: '/canal/clusters',
method: 'get',
params: params
})
}
export function addCanalCluster(data) {
return request({
url: '/canal/cluster',
method: 'post',
data
})
}
export function canalClusterDetail(id) {
return request({
url: '/canal/cluster/' + id,
method: 'get'
})
}
export function updateCanalCluster(data) {
return request({
url: '/canal/cluster',
method: 'put',
data
})
}
export function deleteCanalCluster(id) {
return request({
url: '/canal/cluster/' + id,
method: 'delete'
})
}
export function getClustersAndServers() {
return request({
url: '/canal/clustersAndServers',
method: 'get'
})
}

View File

@@ -0,0 +1,23 @@
import request from '@/utils/request'
export function getCanalConfig(clusterId, serverId) {
return request({
url: '/canal/config/' + clusterId + '/' + serverId,
method: 'get'
})
}
export function updateCanalConfig(data) {
return request({
url: '/canal/config',
method: 'put',
data
})
}
export function getTemplateConfig() {
return request({
url: '/canal/config/template',
method: 'get'
})
}

View File

@@ -0,0 +1,81 @@
import request from '@/utils/request'
export function getCanalInstances(params) {
return request({
url: '/canal/instances',
method: 'get',
params: params
})
}
export function canalInstanceDetail(id) {
return request({
url: '/canal/instance/' + id,
method: 'get'
})
}
export function updateCanalInstance(data) {
return request({
url: '/canal/instance',
method: 'put',
data
})
}
export function addCanalInstance(data) {
return request({
url: '/canal/instance',
method: 'post',
data
})
}
export function deleteCanalInstance(id) {
return request({
url: '/canal/instance/' + id,
method: 'delete'
})
}
export function startInstance(id, nodeId) {
return request({
url: '/canal/instance/start/' + id + '/' + nodeId,
method: 'put'
})
}
export function stopInstance(id, nodeId) {
return request({
url: '/canal/instance/stop/' + id + '/' + nodeId,
method: 'put'
})
}
export function instanceLog(id, nodeId) {
return request({
url: '/canal/instance/log/' + id + '/' + nodeId,
method: 'get'
})
}
export function instanceStatus(id, option) {
return request({
url: '/canal/instance/status/' + id + '?option=' + option,
method: 'put'
})
}
export function getActiveInstances(serverId) {
return request({
url: '/canal/active/instances/' + serverId,
method: 'get'
})
}
export function getTemplateInstance() {
return request({
url: '/canal/instance/template',
method: 'get'
})
}

View File

@@ -0,0 +1,60 @@
import request from '@/utils/request'
export function getNodeServers(params) {
return request({
url: '/nodeServers',
method: 'get',
params: params
})
}
export function addNodeServer(data) {
return request({
url: '/nodeServer',
method: 'post',
data
})
}
export function nodeServerDetail(id) {
return request({
url: '/nodeServer/' + id,
method: 'get'
})
}
export function updateNodeServer(data) {
return request({
url: '/nodeServer',
method: 'put',
data
})
}
export function deleteNodeServer(id) {
return request({
url: '/nodeServer/' + id,
method: 'delete'
})
}
export function startNodeServer(id) {
return request({
url: '/nodeServer/start/' + id,
method: 'put'
})
}
export function stopNodeServer(id) {
return request({
url: '/nodeServer/stop/' + id,
method: 'put'
})
}
export function nodeServerLog(id) {
return request({
url: '/nodeServer/log/' + id,
method: 'get'
})
}

View File

@@ -0,0 +1,9 @@
import request from '@/utils/request'
export function getList(params) {
return request({
url: '/table/list',
method: 'get',
params
})
}

View File

@@ -0,0 +1,32 @@
import request from '@/utils/request'
export function login(data) {
return request({
url: '/user/login',
method: 'post',
data
})
}
export function getInfo(token) {
return request({
url: '/user/info',
method: 'get',
params: { token }
})
}
export function logout() {
return request({
url: '/user/logout',
method: 'post'
})
}
export function updateUser(data) {
return request({
url: '/user',
method: 'put',
data
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@@ -0,0 +1,78 @@
<template>
<el-breadcrumb class="app-breadcrumb" separator="/">
<transition-group name="breadcrumb">
<el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
<span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{ item.meta.title }}</span>
<a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
</el-breadcrumb-item>
</transition-group>
</el-breadcrumb>
</template>
<script>
import pathToRegexp from 'path-to-regexp'
export default {
data() {
return {
levelList: null
}
},
watch: {
$route() {
this.getBreadcrumb()
}
},
created() {
this.getBreadcrumb()
},
methods: {
getBreadcrumb() {
// only show routes with meta.title
let matched = this.$route.matched.filter(item => item.meta && item.meta.title)
const first = matched[0]
if (!this.isDashboard(first)) {
matched = [{ path: '/dashboard', meta: { title: '主页' }}].concat(matched)
}
this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
},
isDashboard(route) {
const name = route && route.name
if (!name) {
return false
}
return name.trim().toLocaleLowerCase() === 'Dashboard'.toLocaleLowerCase()
},
pathCompile(path) {
// To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561
const { params } = this.$route
var toPath = pathToRegexp.compile(path)
return toPath(params)
},
handleLink(item) {
const { redirect, path } = item
if (redirect) {
this.$router.push(redirect)
return
}
this.$router.push(this.pathCompile(path))
}
}
}
</script>
<style lang="scss" scoped>
.app-breadcrumb.el-breadcrumb {
display: inline-block;
font-size: 14px;
line-height: 50px;
margin-left: 8px;
.no-redirect {
color: #97a8be;
cursor: text;
}
}
</style>

View File

@@ -0,0 +1,44 @@
<template>
<div style="padding: 0 15px;" @click="toggleClick">
<svg
:class="{'is-active':isActive}"
class="hamburger"
viewBox="0 0 1024 1024"
xmlns="http://www.w3.org/2000/svg"
width="64"
height="64"
>
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" />
</svg>
</div>
</template>
<script>
export default {
name: 'Hamburger',
props: {
isActive: {
type: Boolean,
default: false
}
},
methods: {
toggleClick() {
this.$emit('toggleClick')
}
}
}
</script>
<style scoped>
.hamburger {
display: inline-block;
vertical-align: middle;
width: 20px;
height: 20px;
}
.hamburger.is-active {
transform: rotate(180deg);
}
</style>

View File

@@ -0,0 +1,101 @@
<template>
<div :class="{'hidden':hidden}" class="pagination-container">
<el-pagination
:background="background"
:current-page.sync="currentPage"
:page-size.sync="pageSize"
:layout="layout"
:page-sizes="pageSizes"
:total="total"
v-bind="$attrs"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</template>
<script>
import { scrollTo } from '@/utils/scrollTo'
export default {
name: 'Pagination',
props: {
total: {
required: true,
type: Number
},
page: {
type: Number,
default: 1
},
limit: {
type: Number,
default: 20
},
pageSizes: {
type: Array,
default() {
return [10, 20, 30, 50]
}
},
layout: {
type: String,
default: 'total, sizes, prev, pager, next, jumper'
},
background: {
type: Boolean,
default: true
},
autoScroll: {
type: Boolean,
default: true
},
hidden: {
type: Boolean,
default: false
}
},
computed: {
currentPage: {
get() {
return this.page
},
set(val) {
this.$emit('update:page', val)
}
},
pageSize: {
get() {
return this.limit
},
set(val) {
this.$emit('update:limit', val)
}
}
},
methods: {
handleSizeChange(val) {
this.$emit('pagination', { page: this.currentPage, limit: val })
if (this.autoScroll) {
scrollTo(0, 800)
}
},
handleCurrentChange(val) {
this.$emit('pagination', { page: val, limit: this.pageSize })
if (this.autoScroll) {
scrollTo(0, 800)
}
}
}
}
</script>
<style scoped>
.pagination-container {
background: #fff;
padding: 32px 16px;
}
.pagination-container.hidden {
display: none;
}
</style>

View File

@@ -0,0 +1,62 @@
<template>
<div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
<svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
<use :xlink:href="iconName" />
</svg>
</template>
<script>
// doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage
import { isExternal } from '@/utils/validate'
export default {
name: 'SvgIcon',
props: {
iconClass: {
type: String,
required: true
},
className: {
type: String,
default: ''
}
},
computed: {
isExternal() {
return isExternal(this.iconClass)
},
iconName() {
return `#icon-${this.iconClass}`
},
svgClass() {
if (this.className) {
return 'svg-icon ' + this.className
} else {
return 'svg-icon'
}
},
styleExternalIcon() {
return {
mask: `url(${this.iconClass}) no-repeat 50% 50%`,
'-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
}
}
}
}
</script>
<style scoped>
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
.svg-external-icon {
background-color: currentColor;
mask-size: cover!important;
display: inline-block;
}
</style>

View File

@@ -0,0 +1,9 @@
import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon'// svg component
// register globally
Vue.component('svg-icon', SvgIcon)
const req = require.context('./svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys().map(requireContext)
requireAll(req)

View File

@@ -0,0 +1 @@
<svg width="128" height="100" xmlns="http://www.w3.org/2000/svg"><path d="M27.429 63.638c0-2.508-.893-4.65-2.679-6.424-1.786-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.465 2.662-1.785 1.774-2.678 3.916-2.678 6.424 0 2.508.893 4.65 2.678 6.424 1.786 1.775 3.94 2.662 6.465 2.662 2.524 0 4.678-.887 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zm13.714-31.801c0-2.508-.893-4.65-2.679-6.424-1.785-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zM71.714 65.98l7.215-27.116c.285-1.23.107-2.378-.536-3.443-.643-1.064-1.56-1.762-2.75-2.094-1.19-.33-2.333-.177-3.429.462-1.095.639-1.81 1.573-2.143 2.804l-7.214 27.116c-2.857.237-5.405 1.266-7.643 3.088-2.238 1.822-3.738 4.152-4.5 6.992-.952 3.644-.476 7.098 1.429 10.364 1.905 3.265 4.69 5.37 8.357 6.317 3.667.947 7.143.474 10.429-1.42 3.285-1.892 5.404-4.66 6.357-8.305.762-2.84.619-5.607-.429-8.305-1.047-2.697-2.762-4.85-5.143-6.46zm47.143-2.342c0-2.508-.893-4.65-2.678-6.424-1.786-1.775-3.94-2.662-6.465-2.662-2.524 0-4.678.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.786 1.775 3.94 2.662 6.464 2.662 2.524 0 4.679-.887 6.465-2.662 1.785-1.775 2.678-3.916 2.678-6.424zm-45.714-45.43c0-2.509-.893-4.65-2.679-6.425C68.68 10.01 66.524 9.122 64 9.122c-2.524 0-4.679.887-6.464 2.661-1.786 1.775-2.679 3.916-2.679 6.425 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zm32 13.629c0-2.508-.893-4.65-2.679-6.424-1.785-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zM128 63.638c0 12.351-3.357 23.78-10.071 34.286-.905 1.372-2.19 2.058-3.858 2.058H13.93c-1.667 0-2.953-.686-3.858-2.058C3.357 87.465 0 76.037 0 63.638c0-8.613 1.69-16.847 5.071-24.703C8.452 31.08 13 24.312 18.714 18.634c5.715-5.68 12.524-10.199 20.429-13.559C47.048 1.715 55.333.035 64 .035c8.667 0 16.952 1.68 24.857 5.04 7.905 3.36 14.714 7.88 20.429 13.559 5.714 5.678 10.262 12.446 13.643 20.301 3.38 7.856 5.071 16.09 5.071 24.703z"/></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M96.258 57.462h31.421C124.794 27.323 100.426 2.956 70.287.07v31.422a32.856 32.856 0 0 1 25.971 25.97zm-38.796-25.97V.07C27.323 2.956 2.956 27.323.07 57.462h31.422a32.856 32.856 0 0 1 25.97-25.97zm12.825 64.766v31.421c30.46-2.885 54.507-27.253 57.713-57.712H96.579c-2.886 13.466-13.146 23.726-26.292 26.291zM31.492 70.287H.07c2.886 30.46 27.253 54.507 57.713 57.713V96.579c-13.466-2.886-23.726-13.146-26.291-26.292z"/></svg>

After

Width:  |  Height:  |  Size: 497 B

View File

@@ -0,0 +1 @@
<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="128" height="128"><defs><style/></defs><path d="M512 128q69.675 0 135.51 21.163t115.498 54.997 93.483 74.837 73.685 82.006 51.67 74.837 32.17 54.827L1024 512q-2.347 4.992-6.315 13.483T998.87 560.17t-31.658 51.669-44.331 59.99-56.832 64.34-69.504 60.16-82.347 51.5-94.848 34.687T512 896q-69.675 0-135.51-21.163t-115.498-54.826-93.483-74.326-73.685-81.493-51.67-74.496-32.17-54.997L0 513.707q2.347-4.992 6.315-13.483t18.816-34.816 31.658-51.84 44.331-60.33 56.832-64.683 69.504-60.331 82.347-51.84 94.848-34.816T512 128.085zm0 85.333q-46.677 0-91.648 12.331t-81.152 31.83-70.656 47.146-59.648 54.485-48.853 57.686-37.675 52.821-26.325 43.99q12.33 21.674 26.325 43.52t37.675 52.351 48.853 57.003 59.648 53.845T339.2 767.02t81.152 31.488T512 810.667t91.648-12.331 81.152-31.659 70.656-46.848 59.648-54.186 48.853-57.344 37.675-52.651T927.957 512q-12.33-21.675-26.325-43.648t-37.675-52.65-48.853-57.345-59.648-54.186-70.656-46.848-81.152-31.659T512 213.334zm0 128q70.656 0 120.661 50.006T682.667 512 632.66 632.661 512 682.667 391.339 632.66 341.333 512t50.006-120.661T512 341.333zm0 85.334q-35.328 0-60.33 25.002T426.666 512t25.002 60.33T512 597.334t60.33-25.002T597.334 512t-25.002-60.33T512 426.666z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1 @@
<svg width="128" height="64" xmlns="http://www.w3.org/2000/svg"><path d="M127.072 7.994c1.37-2.208.914-5.152-.914-6.87-2.056-1.717-4.797-1.226-6.396.982-.229.245-25.586 32.382-55.74 32.382-29.24 0-55.74-32.382-55.968-32.627-1.6-1.963-4.57-2.208-6.397-.49C-.17 3.086-.399 6.275 1.2 8.238c.457.736 5.94 7.36 14.62 14.72L4.17 35.96c-1.828 1.963-1.6 5.152.228 6.87.457.98 1.6 1.471 2.742 1.471s2.284-.49 3.198-1.472l12.564-13.983c5.94 4.416 13.021 8.587 20.788 11.53l-4.797 17.418c-.685 2.699.686 5.397 3.198 6.133h1.37c2.057 0 3.884-1.472 4.341-3.68L52.6 42.83c3.655.736 7.538 1.227 11.422 1.227 3.883 0 7.767-.49 11.422-1.227l4.797 17.173c.457 2.208 2.513 3.68 4.34 3.68.457 0 .914 0 1.143-.246 2.513-.736 3.883-3.434 3.198-6.133l-4.797-17.172c7.767-2.944 14.848-7.114 20.788-11.53l12.336 13.738c.913.981 2.056 1.472 3.198 1.472s2.284-.49 3.198-1.472c1.828-1.963 1.828-4.906.228-6.87l-11.65-13.001c9.366-7.36 14.849-14.474 14.849-14.474z"/></svg>

After

Width:  |  Height:  |  Size: 944 B

View File

@@ -0,0 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M84.068 23.784c-1.02 0-1.877-.32-2.572-.96a8.588 8.588 0 0 1-1.738-2.237 11.524 11.524 0 0 1-1.042-2.621c-.232-.895-.348-1.641-.348-2.238V0h.278c.834 0 1.622.085 2.363.256.742.17 1.645.575 2.711 1.214 1.066.64 2.363 1.535 3.892 2.686 1.53 1.15 3.453 2.664 5.77 4.54 2.502 2.045 4.494 3.771 5.977 5.178 1.483 1.406 2.618 2.6 3.406 3.58.787.98 1.274 1.812 1.46 2.494.185.682.277 1.278.277 1.79v2.046H84.068zM127.3 84.01c.278.682.464 1.535.556 2.558.093 1.023-.37 2.003-1.39 2.94-.463.427-.88.832-1.25 1.215-.372.384-.696.704-.974.96a6.69 6.69 0 0 1-.973.767l-11.816-10.741a44.331 44.331 0 0 0 1.877-1.535 31.028 31.028 0 0 1 1.737-1.406c1.112-.938 2.317-1.343 3.615-1.215 1.297.128 2.363.405 3.197.83.927.427 1.923 1.173 2.989 2.239 1.065 1.065 1.876 2.195 2.432 3.388zM78.23 95.902c2.038 0 3.752-.511 5.143-1.534l-26.969 25.83H18.037c-1.761 0-3.684-.47-5.77-1.407a24.549 24.549 0 0 1-5.838-3.709 21.373 21.373 0 0 1-4.518-5.306c-1.204-2.003-1.807-4.07-1.807-6.202V16.495c0-1.79.44-3.665 1.32-5.626A18.41 18.41 0 0 1 5.04 5.562a21.798 21.798 0 0 1 5.213-3.964C12.198.533 14.237 0 16.37 0h53.24v15.984c0 1.62.278 3.367.834 5.242a16.704 16.704 0 0 0 2.572 5.179c1.159 1.577 2.665 2.898 4.518 3.964 1.853 1.066 4.078 1.598 6.673 1.598h20.295v42.325L85.458 92.45c1.02-1.364 1.529-2.856 1.529-4.476 0-2.216-.857-4.113-2.572-5.69-1.714-1.577-3.776-2.366-6.186-2.366H26.1c-2.409 0-4.448.789-6.116 2.366-1.668 1.577-2.502 3.474-2.502 5.69 0 2.217.834 4.092 2.502 5.626 1.668 1.535 3.707 2.302 6.117 2.302h52.13zM26.1 47.951c-2.41 0-4.449.789-6.117 2.366-1.668 1.577-2.502 3.473-2.502 5.69 0 2.216.834 4.092 2.502 5.626 1.668 1.534 3.707 2.302 6.117 2.302h52.13c2.409 0 4.47-.768 6.185-2.302 1.715-1.534 2.572-3.41 2.572-5.626 0-2.217-.857-4.113-2.572-5.69-1.714-1.577-3.776-2.366-6.186-2.366H26.1zm52.407 64.063l1.807-1.663 3.476-3.196a479.75 479.75 0 0 0 4.587-4.284 500.757 500.757 0 0 1 5.004-4.667c3.985-3.666 8.48-7.758 13.485-12.276l11.677 10.741-13.485 12.404-5.004 4.603-4.587 4.22a179.46 179.46 0 0 0-3.267 3.068c-.88.853-1.367 1.322-1.46 1.407-.463.341-.973.703-1.529 1.087-.556.383-1.112.703-1.668.959-.556.256-1.413.575-2.572.959a83.5 83.5 0 0 1-3.545 1.087 72.2 72.2 0 0 1-3.475.895c-1.112.256-1.946.426-2.502.511-1.112.17-1.854.043-2.224-.383-.371-.426-.464-1.151-.278-2.174.092-.511.278-1.279.556-2.302.278-1.023.602-2.067.973-3.132l1.042-3.005c.325-.938.58-1.577.765-1.918a10.157 10.157 0 0 1 2.224-2.941z"/></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -0,0 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M115.625 127.937H.063V12.375h57.781v12.374H12.438v90.813h90.813V70.156h12.374z"/><path d="M116.426 2.821l8.753 8.753-56.734 56.734-8.753-8.745z"/><path d="M127.893 37.982h-12.375V12.375H88.706V0h39.187z"/></svg>

After

Width:  |  Height:  |  Size: 285 B

View File

@@ -0,0 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.002 9.2c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-5.043-3.58-9.132-7.997-9.132S.002 4.157.002 9.2zM31.997.066h95.981V18.33H31.997V.066zm0 45.669c0 5.044 3.58 9.132 7.998 9.132 4.417 0 7.997-4.088 7.997-9.132 0-3.263-1.524-6.278-3.998-7.91-2.475-1.63-5.524-1.63-7.998 0-2.475 1.632-4 4.647-4 7.91zM63.992 36.6h63.986v18.265H63.992V36.6zm-31.995 82.2c0 5.043 3.58 9.132 7.998 9.132 4.417 0 7.997-4.089 7.997-9.132 0-5.044-3.58-9.133-7.997-9.133s-7.998 4.089-7.998 9.133zm31.995-9.131h63.986v18.265H63.992V109.67zm0-27.404c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-3.263-1.524-6.277-3.998-7.909-2.475-1.631-5.524-1.631-7.998 0-2.475 1.632-4 4.646-4 7.91zm31.995-9.13h31.991V91.4H95.987V73.135z"/></svg>

After

Width:  |  Height:  |  Size: 821 B

View File

@@ -0,0 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M108.8 44.322H89.6v-5.36c0-9.04-3.308-24.163-25.6-24.163-23.145 0-25.6 16.881-25.6 24.162v5.361H19.2v-5.36C19.2 15.281 36.798 0 64 0c27.202 0 44.8 15.281 44.8 38.961v5.361zm-32 39.356c0-5.44-5.763-9.832-12.8-9.832-7.037 0-12.8 4.392-12.8 9.832 0 3.682 2.567 6.808 6.407 8.477v11.205c0 2.718 2.875 4.962 6.4 4.962 3.524 0 6.4-2.244 6.4-4.962V92.155c3.833-1.669 6.393-4.795 6.393-8.477zM128 64v49.201c0 8.158-8.645 14.799-19.2 14.799H19.2C8.651 128 0 121.359 0 113.201V64c0-8.153 8.645-14.799 19.2-14.799h89.6c10.555 0 19.2 6.646 19.2 14.799z"/></svg>

After

Width:  |  Height:  |  Size: 623 B

View File

@@ -0,0 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/></svg>

After

Width:  |  Height:  |  Size: 597 B

View File

@@ -0,0 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M126.713 90.023c.858.985 1.287 2.134 1.287 3.447v29.553c0 1.423-.429 2.6-1.287 3.53-.858.93-1.907 1.395-3.146 1.395H97.824c-1.145 0-2.146-.465-3.004-1.395-.858-.93-1.287-2.107-1.287-3.53V93.47c0-.875.19-1.696.572-2.462.382-.766.906-1.368 1.573-1.806a3.84 3.84 0 0 1 2.146-.657h9.725V69.007a3.84 3.84 0 0 0-.43-1.806 3.569 3.569 0 0 0-1.143-1.313 2.714 2.714 0 0 0-1.573-.492h-36.47v23.149h9.725c1.144 0 2.145.492 3.004 1.478.858.985 1.287 2.134 1.287 3.447v29.553c0 .876-.191 1.696-.573 2.463-.38.766-.905 1.368-1.573 1.806a3.84 3.84 0 0 1-2.145.656H51.915a3.84 3.84 0 0 1-2.145-.656c-.668-.438-1.216-1.04-1.645-1.806a4.96 4.96 0 0 1-.644-2.463V93.47c0-1.313.43-2.462 1.288-3.447.858-.986 1.907-1.478 3.146-1.478h9.582v-23.15h-37.9c-.953 0-1.74.356-2.359 1.068-.62.711-.93 1.56-.93 2.544v19.538h9.726c1.239 0 2.264.492 3.074 1.478.81.985 1.216 2.134 1.216 3.447v29.553c0 1.423-.405 2.6-1.216 3.53-.81.93-1.835 1.395-3.074 1.395H4.29c-.476 0-.93-.082-1.358-.246a4.1 4.1 0 0 1-1.144-.657 4.658 4.658 0 0 1-.93-1.067 5.186 5.186 0 0 1-.643-1.395 5.566 5.566 0 0 1-.215-1.56V93.47c0-.437.048-.875.143-1.313a3.95 3.95 0 0 1 .429-1.15c.19-.328.429-.656.715-.984.286-.329.572-.602.858-.821.286-.22.62-.383 1.001-.493.382-.11.763-.164 1.144-.164h9.726V61.619c0-.985.31-1.833.93-2.544.619-.712 1.358-1.068 2.216-1.068h44.335V39.62h-9.582c-1.24 0-2.288-.492-3.146-1.477a5.09 5.09 0 0 1-1.287-3.448V5.14c0-1.423.429-2.627 1.287-3.612.858-.985 1.907-1.477 3.146-1.477h25.743c.763 0 1.478.246 2.145.739a5.17 5.17 0 0 1 1.573 1.888c.382.766.573 1.587.573 2.462v29.553c0 1.313-.43 2.463-1.287 3.448-.859.985-1.86 1.477-3.004 1.477h-9.725v18.389h42.762c.954 0 1.74.355 2.36 1.067.62.711.93 1.56.93 2.545v26.925h9.582c1.239 0 2.288.492 3.146 1.478z"/></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1 @@
<svg width="130" height="130" xmlns="http://www.w3.org/2000/svg"><path d="M63.444 64.996c20.633 0 37.359-14.308 37.359-31.953 0-17.649-16.726-31.952-37.359-31.952-20.631 0-37.36 14.303-37.358 31.952 0 17.645 16.727 31.953 37.359 31.953zM80.57 75.65H49.434c-26.652 0-48.26 18.477-48.26 41.27v2.664c0 9.316 21.608 9.325 48.26 9.325H80.57c26.649 0 48.256-.344 48.256-9.325v-2.663c0-22.794-21.605-41.271-48.256-41.271z" stroke="#979797"/></svg>

After

Width:  |  Height:  |  Size: 440 B

View File

@@ -0,0 +1,22 @@
# replace default config
# multipass: true
# full: true
plugins:
# - name
#
# or:
# - name: false
# - name: true
#
# or:
# - name:
# param1: 1
# param2: 2
- removeAttrs:
attrs:
- 'fill'
- 'fill-rule'

View File

@@ -0,0 +1,40 @@
<template>
<section class="app-main">
<transition name="fade-transform" mode="out-in">
<router-view :key="key" />
</transition>
</section>
</template>
<script>
export default {
name: 'AppMain',
computed: {
key() {
return this.$route.path
}
}
}
</script>
<style scoped>
.app-main {
/*50 = navbar */
min-height: calc(100vh - 50px);
width: 100%;
position: relative;
overflow: hidden;
}
.fixed-header+.app-main {
padding-top: 50px;
}
</style>
<style lang="scss">
// fix css style bug in open el-dialog
.el-popup-parent--hidden {
.fixed-header {
padding-right: 15px;
}
}
</style>

View File

@@ -0,0 +1,142 @@
<template>
<div class="navbar">
<hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
<breadcrumb class="breadcrumb-container" />
<div class="right-menu">
<el-dropdown class="avatar-container" trigger="click">
<div class="avatar-wrapper">
<!-- avatar+'?imageView2/1/w/80/h/80' -->
<img :src="avat+'?imageView2/1/w/80/h/80'" class="user-avatar">
<i class="el-icon-caret-bottom" />
</div>
<el-dropdown-menu slot="dropdown" class="user-dropdown">
<router-link to="/">
<el-dropdown-item>
主页
</el-dropdown-item>
</router-link>
<router-link to="/sys/user">
<el-dropdown-item>账号管理</el-dropdown-item>
</router-link>
<el-dropdown-item divided>
<span style="display:block;" @click="logout">退出</span>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import Breadcrumb from '@/components/Breadcrumb'
import Hamburger from '@/components/Hamburger'
export default {
components: {
Breadcrumb,
Hamburger
},
data() {
return {
avat: './avatar.gif'
}
},
computed: {
...mapGetters([
'sidebar',
'avatar'
])
},
methods: {
toggleSideBar() {
this.$store.dispatch('app/toggleSideBar')
},
async logout() {
await this.$store.dispatch('user/logout')
this.$router.push(`/login?redirect=${this.$route.fullPath}`)
}
}
}
</script>
<style lang="scss" scoped>
.navbar {
height: 50px;
overflow: hidden;
position: relative;
background: #fff;
box-shadow: 0 1px 4px rgba(0,21,41,.08);
.hamburger-container {
line-height: 46px;
height: 100%;
float: left;
cursor: pointer;
transition: background .3s;
-webkit-tap-highlight-color:transparent;
&:hover {
background: rgba(0, 0, 0, .025)
}
}
.breadcrumb-container {
float: left;
}
.right-menu {
float: right;
height: 100%;
line-height: 50px;
&:focus {
outline: none;
}
.right-menu-item {
display: inline-block;
padding: 0 8px;
height: 100%;
font-size: 18px;
color: #5a5e66;
vertical-align: text-bottom;
&.hover-effect {
cursor: pointer;
transition: background .3s;
&:hover {
background: rgba(0, 0, 0, .025)
}
}
}
.avatar-container {
margin-right: 30px;
.avatar-wrapper {
margin-top: 5px;
position: relative;
.user-avatar {
cursor: pointer;
width: 40px;
height: 40px;
border-radius: 10px;
}
.el-icon-caret-bottom {
cursor: pointer;
position: absolute;
right: -20px;
top: 25px;
font-size: 12px;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,26 @@
export default {
computed: {
device() {
return this.$store.state.app.device
}
},
mounted() {
// In order to fix the click on menu on the ios device will trigger the mouseleave bug
// https://github.com/PanJiaChen/vue-element-admin/issues/1135
this.fixBugIniOS()
},
methods: {
fixBugIniOS() {
const $subMenu = this.$refs.subMenu
if ($subMenu) {
const handleMouseleave = $subMenu.handleMouseleave
$subMenu.handleMouseleave = (e) => {
if (this.device === 'mobile') {
return
}
handleMouseleave(e)
}
}
}
}
}

View File

@@ -0,0 +1,29 @@
<script>
export default {
name: 'MenuItem',
functional: true,
props: {
icon: {
type: String,
default: ''
},
title: {
type: String,
default: ''
}
},
render(h, context) {
const { icon, title } = context.props
const vnodes = []
if (icon) {
vnodes.push(<svg-icon icon-class={icon}/>)
}
if (title) {
vnodes.push(<span slot='title'>{(title)}</span>)
}
return vnodes
}
}
</script>

View File

@@ -0,0 +1,36 @@
<template>
<!-- eslint-disable vue/require-component-is -->
<component v-bind="linkProps(to)">
<slot />
</component>
</template>
<script>
import { isExternal } from '@/utils/validate'
export default {
props: {
to: {
type: String,
required: true
}
},
methods: {
linkProps(url) {
if (isExternal(url)) {
return {
is: 'a',
href: url,
target: '_blank',
rel: 'noopener'
}
}
return {
is: 'router-link',
to: url
}
}
}
}
</script>

View File

@@ -0,0 +1,82 @@
<template>
<div class="sidebar-logo-container" :class="{'collapse':collapse}">
<transition name="sidebarLogoFade">
<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
<img v-if="logo" :src="logo" class="sidebar-logo">
<h1 v-else class="sidebar-title">{{ title }} </h1>
</router-link>
<router-link v-else key="expand" class="sidebar-logo-link" to="/">
<img v-if="logo" :src="logo" class="sidebar-logo">
<h1 class="sidebar-title">{{ title }} </h1>
</router-link>
</transition>
</div>
</template>
<script>
export default {
name: 'SidebarLogo',
props: {
collapse: {
type: Boolean,
required: true
}
},
data() {
return {
title: '',
logo: './logo.png'
}
}
}
</script>
<style lang="scss" scoped>
.sidebarLogoFade-enter-active {
transition: opacity 1.5s;
}
.sidebarLogoFade-enter,
.sidebarLogoFade-leave-to {
opacity: 0;
}
.sidebar-logo-container {
position: relative;
width: 100%;
height: 50px;
line-height: 50px;
background: #2b2f3a;
text-align: center;
overflow: hidden;
& .sidebar-logo-link {
height: 100%;
width: 100%;
& .sidebar-logo {
width: 55px;
// height: 32px;
vertical-align: middle;
margin-right: 12px;
}
& .sidebar-title {
display: inline-block;
margin: 0;
color: #fff;
font-weight: 600;
line-height: 50px;
font-size: 14px;
font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
vertical-align: middle;
}
}
&.collapse {
.sidebar-logo {
margin-right: 0px;
}
}
}
</style>

View File

@@ -0,0 +1,95 @@
<template>
<div v-if="!item.hidden" class="menu-wrapper">
<template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
<app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
<el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}">
<item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="onlyOneChild.meta.title" />
</el-menu-item>
</app-link>
</template>
<el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>
<template slot="title">
<item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" />
</template>
<sidebar-item
v-for="child in item.children"
:key="child.path"
:is-nest="true"
:item="child"
:base-path="resolvePath(child.path)"
class="nest-menu"
/>
</el-submenu>
</div>
</template>
<script>
import path from 'path'
import { isExternal } from '@/utils/validate'
import Item from './Item'
import AppLink from './Link'
import FixiOSBug from './FixiOSBug'
export default {
name: 'SidebarItem',
components: { Item, AppLink },
mixins: [FixiOSBug],
props: {
// route object
item: {
type: Object,
required: true
},
isNest: {
type: Boolean,
default: false
},
basePath: {
type: String,
default: ''
}
},
data() {
// To fix https://github.com/PanJiaChen/vue-admin-template/issues/237
// TODO: refactor with render function
this.onlyOneChild = null
return {}
},
methods: {
hasOneShowingChild(children = [], parent) {
const showingChildren = children.filter(item => {
if (item.hidden) {
return false
} else {
// Temp set(will be used if only has one showing child)
this.onlyOneChild = item
return true
}
})
// When there is only one child router, the child router is displayed by default
if (showingChildren.length === 1) {
return true
}
// Show parent if there are no child router to display
if (showingChildren.length === 0) {
this.onlyOneChild = { ... parent, path: '', noShowingChildren: true }
return true
}
return false
},
resolvePath(routePath) {
if (isExternal(routePath)) {
return routePath
}
if (isExternal(this.basePath)) {
return this.basePath
}
return path.resolve(this.basePath, routePath)
}
}
}
</script>

View File

@@ -0,0 +1,56 @@
<template>
<div :class="{'has-logo':showLogo}">
<logo v-if="showLogo" :collapse="isCollapse" />
<el-scrollbar wrap-class="scrollbar-wrapper">
<el-menu
:default-active="activeMenu"
:collapse="isCollapse"
:background-color="variables.menuBg"
:text-color="variables.menuText"
:unique-opened="false"
:active-text-color="variables.menuActiveText"
:collapse-transition="false"
mode="vertical"
>
<sidebar-item v-for="route in routes" :key="route.path" :item="route" :base-path="route.path" />
</el-menu>
</el-scrollbar>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import Logo from './Logo'
import SidebarItem from './SidebarItem'
import variables from '@/styles/variables.scss'
export default {
components: { SidebarItem, Logo },
computed: {
...mapGetters([
'sidebar'
]),
routes() {
return this.$router.options.routes
},
activeMenu() {
const route = this.$route
const { meta, path } = route
// if set path, the sidebar will highlight the path you set
if (meta.activeMenu) {
return meta.activeMenu
}
return path
},
showLogo() {
return this.$store.state.settings.sidebarLogo
},
variables() {
return variables
},
isCollapse() {
return !this.sidebar.opened
}
}
}
</script>

View File

@@ -0,0 +1,3 @@
export { default as Navbar } from './Navbar'
export { default as Sidebar } from './Sidebar'
export { default as AppMain } from './AppMain'

View File

@@ -0,0 +1,93 @@
<template>
<div :class="classObj" class="app-wrapper">
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
<sidebar class="sidebar-container" />
<div class="main-container">
<div :class="{'fixed-header':fixedHeader}">
<navbar />
</div>
<app-main />
</div>
</div>
</template>
<script>
import { Navbar, Sidebar, AppMain } from './components'
import ResizeMixin from './mixin/ResizeHandler'
export default {
name: 'Layout',
components: {
Navbar,
Sidebar,
AppMain
},
mixins: [ResizeMixin],
computed: {
sidebar() {
return this.$store.state.app.sidebar
},
device() {
return this.$store.state.app.device
},
fixedHeader() {
return this.$store.state.settings.fixedHeader
},
classObj() {
return {
hideSidebar: !this.sidebar.opened,
openSidebar: this.sidebar.opened,
withoutAnimation: this.sidebar.withoutAnimation,
mobile: this.device === 'mobile'
}
}
},
methods: {
handleClickOutside() {
this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
}
}
}
</script>
<style lang="scss" scoped>
@import "~@/styles/mixin.scss";
@import "~@/styles/variables.scss";
.app-wrapper {
@include clearfix;
position: relative;
height: 100%;
width: 100%;
&.mobile.openSidebar{
position: fixed;
top: 0;
}
}
.drawer-bg {
background: #000;
opacity: 0.3;
width: 100%;
top: 0;
height: 100%;
position: absolute;
z-index: 999;
}
.fixed-header {
position: fixed;
top: 0;
right: 0;
z-index: 9;
width: calc(100% - #{$sideBarWidth});
transition: width 0.28s;
}
.hideSidebar .fixed-header {
width: calc(100% - 54px)
}
.mobile .fixed-header {
width: 100%;
}
</style>

View File

@@ -0,0 +1,45 @@
import store from '@/store'
const { body } = document
const WIDTH = 992 // refer to Bootstrap's responsive design
export default {
watch: {
$route(route) {
if (this.device === 'mobile' && this.sidebar.opened) {
store.dispatch('app/closeSideBar', { withoutAnimation: false })
}
}
},
beforeMount() {
window.addEventListener('resize', this.$_resizeHandler)
},
beforeDestroy() {
window.removeEventListener('resize', this.$_resizeHandler)
},
mounted() {
const isMobile = this.$_isMobile()
if (isMobile) {
store.dispatch('app/toggleDevice', 'mobile')
store.dispatch('app/closeSideBar', { withoutAnimation: true })
}
},
methods: {
// use $_ for mixins properties
// https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
$_isMobile() {
const rect = body.getBoundingClientRect()
return rect.width - 1 < WIDTH
},
$_resizeHandler() {
if (!document.hidden) {
const isMobile = this.$_isMobile()
store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop')
if (isMobile) {
store.dispatch('app/closeSideBar', { withoutAnimation: true })
}
}
}
}
}

View File

@@ -0,0 +1,44 @@
import Vue from 'vue'
import 'normalize.css/normalize.css' // A modern alternative to CSS resets
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import locale from 'element-ui/lib/locale/lang/en' // lang i18n
import '@/styles/index.scss' // global css
import App from './App'
import store from './store'
import router from './router'
import '@/icons' // icon
import '@/permission' // permission control
/**
* If you don't want to use mock-server
* you want to use MockJs for mock api
* you can execute: mockXHR()
*
* Currently MockJs will be used in the production environment,
* please remove it before going online! ! !
*/
// import { mockXHR } from '../mock'
// if (process.env.NODE_ENV === 'production') {
// mockXHR()
// }
// set ElementUI lang to EN
Vue.use(ElementUI, {
size: 'small',
locale
})
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
store,
render: h => h(App)
})

View File

@@ -0,0 +1,64 @@
import router from './router'
import store from './store'
import { Message } from 'element-ui'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import { getToken } from '@/utils/auth' // get token from cookie
import getPageTitle from '@/utils/get-page-title'
NProgress.configure({ showSpinner: false }) // NProgress Configuration
const whiteList = ['/login'] // no redirect whitelist
router.beforeEach(async(to, from, next) => {
// start progress bar
NProgress.start()
// set page title
document.title = getPageTitle(to.meta.title)
// determine whether the user has logged in
const hasToken = getToken()
if (hasToken) {
if (to.path === '/login') {
// if is logged in, redirect to the home page
next({ path: '/' })
NProgress.done()
} else {
const hasGetUserInfo = store.getters.name
if (hasGetUserInfo) {
next()
} else {
try {
// get user info
await store.dispatch('user/getInfo')
next()
} catch (error) {
// remove token and go to login page to re-login
await store.dispatch('user/resetToken')
Message.error(error || 'Has Error')
next(`/login?redirect=${to.path}`)
NProgress.done()
}
}
}
} else {
/* has no token*/
if (whiteList.indexOf(to.path) !== -1) {
// in the free login whitelist, go directly
next()
} else {
// other pages that do not have permission to access are redirected to the login page.
next(`/login?redirect=${to.path}`)
NProgress.done()
}
}
})
router.afterEach(() => {
// finish progress bar
NProgress.done()
})

View File

@@ -0,0 +1,153 @@
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
/* Layout */
import Layout from '@/layout'
/**
* Note: sub-menu only appear when route children.length >= 1
* Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html
*
* hidden: true if set true, item will not show in the sidebar(default is false)
* alwaysShow: true if set true, will always show the root menu
* if not set alwaysShow, when item has more than one children route,
* it will becomes nested mode, otherwise not show the root menu
* redirect: noRedirect if set noRedirect will no redirect in the breadcrumb
* name:'router-name' the name is used by <keep-alive> (must set!!!)
* meta : {
roles: ['admin','editor'] control the page roles (you can set multiple roles)
title: 'title' the name show in sidebar and breadcrumb (recommend set)
icon: 'svg-name' the icon show in the sidebar
breadcrumb: false if set false, the item will hidden in breadcrumb(default is true)
activeMenu: '/example/list' if set path, the sidebar will highlight the path you set
}
*/
/**
* constantRoutes
* a base page that does not have permission requirements
* all roles can be accessed
*/
export const constantRoutes = [
{
path: '/login',
component: () => import('@/views/login/index'),
hidden: true
},
{
path: '/404',
component: () => import('@/views/404'),
hidden: true
},
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [{
path: 'dashboard',
name: '主页',
component: () => import('@/views/dashboard/index'),
meta: { title: '主页', icon: 'dashboard' }
}],
hidden: true
},
{
path: '/sys',
component: Layout,
redirect: '/user',
children: [{
path: 'user',
name: '用户信息',
component: () => import('@/views/sys/UserInfo'),
meta: { title: '用户信息' }
}],
hidden: true
},
{
path: '/canalServer',
component: Layout,
redirect: '/canalServer/nodeServers',
name: 'Canal Server',
meta: { title: 'Canal Server', icon: 'example' },
children: [
{
path: 'canalClusters',
name: 'Canal 集群管理',
component: () => import('@/views/canalServer/CanalCluster'),
meta: { title: '集群管理', icon: 'tree' }
},
{
path: 'nodeServers',
name: 'Server 状态',
component: () => import('@/views/canalServer/NodeServer'),
meta: { title: 'Server 管理', icon: 'form' }
},
{
path: 'nodeServer/config',
name: 'Server 配置',
component: () => import('@/views/canalServer/CanalConfig'),
meta: { title: 'Server 配置' },
hidden: true
},
{
path: 'canalInstances',
name: 'Instance 管理',
component: () => import('@/views/canalServer/CanalInstance'),
meta: { title: 'Instance 管理', icon: 'nested' }
},
{
path: 'canalInstance/add',
name: '新建Instance配置',
component: () => import('@/views/canalServer/CanalInstanceAdd'),
meta: { title: '新建Instance配置' },
hidden: true
},
{
path: 'canalInstance/modify',
name: '修改Instance配置',
component: () => import('@/views/canalServer/CanalInstanceUpdate'),
meta: { title: '修改Instance配置' },
hidden: true
},
{
path: 'nodeServer/log',
name: 'Server 日志',
component: () => import('@/views/canalServer/CanalLogDetail'),
meta: { title: 'Server 日志' },
hidden: true
},
{
path: 'canalInstance/log',
name: 'Instance 日志',
component: () => import('@/views/canalServer/CanalInstanceLogDetail'),
meta: { title: 'Instance 日志' },
hidden: true
}
]
},
// 404 page must be placed at the end !!!
{ path: '*', redirect: '/404', hidden: true }
]
const createRouter = () => new Router({
// mode: 'history', // require service support
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes
})
const router = createRouter()
// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // reset router
}
export default router

View File

@@ -0,0 +1,16 @@
module.exports = {
title: 'Canal Admin',
/**
* @type {boolean} true | false
* @description Whether fix the header
*/
fixedHeader: true,
/**
* @type {boolean} true | false
* @description Whether show the logo in sidebar
*/
sidebarLogo: true
}

View File

@@ -0,0 +1,8 @@
const getters = {
sidebar: state => state.app.sidebar,
device: state => state.app.device,
token: state => state.user.token,
avatar: state => state.user.avatar,
name: state => state.user.name
}
export default getters

View File

@@ -0,0 +1,19 @@
import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
import app from './modules/app'
import settings from './modules/settings'
import user from './modules/user'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
app,
settings,
user
},
getters
})
export default store

View File

@@ -0,0 +1,48 @@
import Cookies from 'js-cookie'
const state = {
sidebar: {
opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
withoutAnimation: false
},
device: 'desktop'
}
const mutations = {
TOGGLE_SIDEBAR: state => {
state.sidebar.opened = !state.sidebar.opened
state.sidebar.withoutAnimation = false
if (state.sidebar.opened) {
Cookies.set('sidebarStatus', 1)
} else {
Cookies.set('sidebarStatus', 0)
}
},
CLOSE_SIDEBAR: (state, withoutAnimation) => {
Cookies.set('sidebarStatus', 0)
state.sidebar.opened = false
state.sidebar.withoutAnimation = withoutAnimation
},
TOGGLE_DEVICE: (state, device) => {
state.device = device
}
}
const actions = {
toggleSideBar({ commit }) {
commit('TOGGLE_SIDEBAR')
},
closeSideBar({ commit }, { withoutAnimation }) {
commit('CLOSE_SIDEBAR', withoutAnimation)
},
toggleDevice({ commit }, device) {
commit('TOGGLE_DEVICE', device)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}

View File

@@ -0,0 +1,31 @@
import defaultSettings from '@/settings'
const { showSettings, fixedHeader, sidebarLogo } = defaultSettings
const state = {
showSettings: showSettings,
fixedHeader: fixedHeader,
sidebarLogo: sidebarLogo
}
const mutations = {
CHANGE_SETTING: (state, { key, value }) => {
if (state.hasOwnProperty(key)) {
state[key] = value
}
}
}
const actions = {
changeSetting({ commit }, data) {
commit('CHANGE_SETTING', data)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}

View File

@@ -0,0 +1,90 @@
import { login, logout, getInfo } from '@/api/user'
import { getToken, setToken, removeToken } from '@/utils/auth'
import { resetRouter } from '@/router'
const state = {
token: getToken(),
name: '',
avatar: ''
}
const mutations = {
SET_TOKEN: (state, token) => {
state.token = token
},
SET_NAME: (state, name) => {
state.name = name
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar
}
}
const actions = {
// user login
login({ commit }, userInfo) {
const { username, password } = userInfo
return new Promise((resolve, reject) => {
login({ username: username.trim(), password: password }).then(response => {
const { data } = response
commit('SET_TOKEN', data.token)
setToken(data.token)
resolve()
}).catch(error => {
reject(error)
})
})
},
// get user info
getInfo({ commit, state }) {
return new Promise((resolve, reject) => {
getInfo(state.token).then(response => {
const { data } = response
if (!data) {
reject('Verification failed, please Login again.')
}
const { name, avatar } = data
commit('SET_NAME', name)
commit('SET_AVATAR', avatar)
resolve(data)
}).catch(error => {
reject(error)
})
})
},
// user logout
logout({ commit, state }) {
return new Promise((resolve, reject) => {
logout(state.token).then(() => {
commit('SET_TOKEN', '')
removeToken()
resetRouter()
resolve()
}).catch(error => {
reject(error)
})
})
},
// remove token
resetToken({ commit }) {
return new Promise(resolve => {
commit('SET_TOKEN', '')
removeToken()
resolve()
})
}
}
export default {
namespaced: true,
state,
mutations,
actions
}

View File

@@ -0,0 +1,44 @@
// cover some element-ui styles
.el-breadcrumb__inner,
.el-breadcrumb__inner a {
font-weight: 400 !important;
}
.el-upload {
input[type="file"] {
display: none !important;
}
}
.el-upload__input {
display: none;
}
// to fixed https://github.com/ElemeFE/element/issues/2461
.el-dialog {
transform: none;
left: 0;
position: relative;
margin: 0 auto;
}
// refine element ui upload
.upload-container {
.el-upload {
width: 100%;
.el-upload-dragger {
width: 100%;
height: 200px;
}
}
}
// dropdown
.el-dropdown-menu {
a {
display: block
}
}

View File

@@ -0,0 +1,74 @@
@import './variables.scss';
@import './mixin.scss';
@import './transition.scss';
@import './element-ui.scss';
@import './sidebar.scss';
body {
height: 100%;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
}
label {
font-weight: 700;
}
html {
height: 100%;
box-sizing: border-box;
}
#app {
height: 100%;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
a:focus,
a:active {
outline: none;
}
a,
a:focus,
a:hover {
cursor: pointer;
color: inherit;
text-decoration: none;
}
div:focus {
outline: none;
}
.clearfix {
&:after {
visibility: hidden;
display: block;
font-size: 0;
content: " ";
clear: both;
height: 0;
}
}
// main-container global css
.app-container {
padding: 20px;
}
.filter-container {
padding-bottom: 10px;
.filter-item {
display: inline-block;
vertical-align: middle;
margin-bottom: 10px;
}
}

View File

@@ -0,0 +1,28 @@
@mixin clearfix {
&:after {
content: "";
display: table;
clear: both;
}
}
@mixin scrollBar {
&::-webkit-scrollbar-track-piece {
background: #d3dce6;
}
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-thumb {
background: #99a9bf;
border-radius: 20px;
}
}
@mixin relative {
position: relative;
width: 100%;
height: 100%;
}

View File

@@ -0,0 +1,209 @@
#app {
.main-container {
min-height: 100%;
transition: margin-left .28s;
margin-left: $sideBarWidth;
position: relative;
}
.sidebar-container {
transition: width 0.28s;
width: $sideBarWidth !important;
background-color: $menuBg;
height: 100%;
position: fixed;
font-size: 0px;
top: 0;
bottom: 0;
left: 0;
z-index: 1001;
overflow: hidden;
// reset element-ui css
.horizontal-collapse-transition {
transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out;
}
.scrollbar-wrapper {
overflow-x: hidden !important;
}
.el-scrollbar__bar.is-vertical {
right: 0px;
}
.el-scrollbar {
height: 100%;
}
&.has-logo {
.el-scrollbar {
height: calc(100% - 50px);
}
}
.is-horizontal {
display: none;
}
a {
display: inline-block;
width: 100%;
overflow: hidden;
}
.svg-icon {
margin-right: 16px;
}
.el-menu {
border: none;
height: 100%;
width: 100% !important;
}
// menu hover
.submenu-title-noDropdown,
.el-submenu__title {
&:hover {
background-color: $menuHover !important;
}
}
.is-active>.el-submenu__title {
color: $subMenuActiveText !important;
}
& .nest-menu .el-submenu>.el-submenu__title,
& .el-submenu .el-menu-item {
min-width: $sideBarWidth !important;
background-color: $subMenuBg !important;
&:hover {
background-color: $subMenuHover !important;
}
}
}
.hideSidebar {
.sidebar-container {
width: 54px !important;
}
.main-container {
margin-left: 54px;
}
.submenu-title-noDropdown {
padding: 0 !important;
position: relative;
.el-tooltip {
padding: 0 !important;
.svg-icon {
margin-left: 20px;
}
}
}
.el-submenu {
overflow: hidden;
&>.el-submenu__title {
padding: 0 !important;
.svg-icon {
margin-left: 20px;
}
.el-submenu__icon-arrow {
display: none;
}
}
}
.el-menu--collapse {
.el-submenu {
&>.el-submenu__title {
&>span {
height: 0;
width: 0;
overflow: hidden;
visibility: hidden;
display: inline-block;
}
}
}
}
}
.el-menu--collapse .el-menu .el-submenu {
min-width: $sideBarWidth !important;
}
// mobile responsive
.mobile {
.main-container {
margin-left: 0px;
}
.sidebar-container {
transition: transform .28s;
width: $sideBarWidth !important;
}
&.hideSidebar {
.sidebar-container {
pointer-events: none;
transition-duration: 0.3s;
transform: translate3d(-$sideBarWidth, 0, 0);
}
}
}
.withoutAnimation {
.main-container,
.sidebar-container {
transition: none;
}
}
}
// when menu collapsed
.el-menu--vertical {
&>.el-menu {
.svg-icon {
margin-right: 16px;
}
}
.nest-menu .el-submenu>.el-submenu__title,
.el-menu-item {
&:hover {
// you can use $subMenuHover
background-color: $menuHover !important;
}
}
// the scroll bar appears when the subMenu is too long
>.el-menu--popup {
max-height: 100vh;
overflow-y: auto;
&::-webkit-scrollbar-track-piece {
background: #d3dce6;
}
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-thumb {
background: #99a9bf;
border-radius: 20px;
}
}
}

View File

@@ -0,0 +1,48 @@
// global transition css
/* fade */
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.28s;
}
.fade-enter,
.fade-leave-active {
opacity: 0;
}
/* fade-transform */
.fade-transform-leave-active,
.fade-transform-enter-active {
transition: all .5s;
}
.fade-transform-enter {
opacity: 0;
transform: translateX(-30px);
}
.fade-transform-leave-to {
opacity: 0;
transform: translateX(30px);
}
/* breadcrumb transition */
.breadcrumb-enter-active,
.breadcrumb-leave-active {
transition: all .5s;
}
.breadcrumb-enter,
.breadcrumb-leave-active {
opacity: 0;
transform: translateX(20px);
}
.breadcrumb-move {
transition: all .5s;
}
.breadcrumb-leave-active {
position: absolute;
}

View File

@@ -0,0 +1,25 @@
// sidebar
$menuText:#bfcbd9;
$menuActiveText:#409EFF;
$subMenuActiveText:#f4f4f5; //https://github.com/ElemeFE/element/issues/12951
$menuBg:#304156;
$menuHover:#263445;
$subMenuBg:#1f2d3d;
$subMenuHover:#001528;
$sideBarWidth: 210px;
// the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
:export {
menuText: $menuText;
menuActiveText: $menuActiveText;
subMenuActiveText: $subMenuActiveText;
menuBg: $menuBg;
menuHover: $menuHover;
subMenuBg: $subMenuBg;
subMenuHover: $subMenuHover;
sideBarWidth: $sideBarWidth;
}

View File

@@ -0,0 +1,15 @@
import Cookies from 'js-cookie'
const TokenKey = 'canal_admin_token'
export function getToken() {
return Cookies.get(TokenKey)
}
export function setToken(token) {
return Cookies.set(TokenKey, token, { maxAge: 0 })
}
export function removeToken() {
return Cookies.remove(TokenKey)
}

View File

@@ -0,0 +1,10 @@
import defaultSettings from '@/settings'
const title = defaultSettings.title || 'Vue Admin Template'
export default function getPageTitle(pageTitle) {
if (pageTitle) {
return `${pageTitle} - ${title}`
}
return `${title}`
}

View File

@@ -0,0 +1,110 @@
/**
* Created by PanJiaChen on 16/11/18.
*/
/**
* Parse the time to string
* @param {(Object|string|number)} time
* @param {string} cFormat
* @returns {string}
*/
export function parseTime(time, cFormat) {
if (arguments.length === 0) {
return null
}
const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
let date
if (typeof time === 'object') {
date = time
} else {
if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
time = parseInt(time)
}
if ((typeof time === 'number') && (time.toString().length === 10)) {
time = time * 1000
}
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
}
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
let value = formatObj[key]
// Note: getDay() returns 0 on Sunday
if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] }
if (result.length > 0 && value < 10) {
value = '0' + value
}
return value || 0
})
return time_str
}
/**
* @param {number} time
* @param {string} option
* @returns {string}
*/
export function formatTime(time, option) {
if (('' + time).length === 10) {
time = parseInt(time) * 1000
} else {
time = +time
}
const d = new Date(time)
const now = Date.now()
const diff = (now - d) / 1000
if (diff < 30) {
return '刚刚'
} else if (diff < 3600) {
// less 1 hour
return Math.ceil(diff / 60) + '分钟前'
} else if (diff < 3600 * 24) {
return Math.ceil(diff / 3600) + '小时前'
} else if (diff < 3600 * 24 * 2) {
return '1天前'
}
if (option) {
return parseTime(time, option)
} else {
return (
d.getMonth() +
1 +
'月' +
d.getDate() +
'日' +
d.getHours() +
'时' +
d.getMinutes() +
'分'
)
}
}
/**
* @param {string} url
* @returns {Object}
*/
export function param2Obj(url) {
const search = url.split('?')[1]
if (!search) {
return {}
}
return JSON.parse(
'{"' +
decodeURIComponent(search)
.replace(/"/g, '\\"')
.replace(/&/g, '","')
.replace(/=/g, '":"')
.replace(/\+/g, ' ') +
'"}'
)
}

View File

@@ -0,0 +1,85 @@
import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
// create an axios instance
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
// withCredentials: true, // send cookies when cross-domain requests
timeout: 60000 // request timeout
})
// request interceptor
service.interceptors.request.use(
config => {
// do something before request is sent
if (store.getters.token) {
// let each request carry token
// ['X-Token'] is a custom headers key
// please modify it according to the actual situation
config.headers['X-Token'] = getToken()
}
return config
},
error => {
// do something with request error
console.log(error) // for debug
return Promise.reject(error)
}
)
// response interceptor
service.interceptors.response.use(
/**
* If you want to get http information such as headers or status
* Please return response => response
*/
/**
* Determine the request status by custom code
* Here is just an example
* You can also judge the status by HTTP Status Code
*/
response => {
const res = response.data
// if the custom code is not 20000, it is judged as an error.
if (res.code !== 20000) {
Message({
message: res.message || 'Error',
type: 'error',
duration: 5 * 1000
})
// 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
// to re-login
MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
confirmButtonText: 'Re-Login',
cancelButtonText: 'Cancel',
type: 'warning'
}).then(() => {
store.dispatch('user/resetToken').then(() => {
location.reload()
})
})
}
return Promise.reject(new Error(res.message || 'Error'))
} else {
return res
}
},
error => {
console.log('err' + error) // for debug
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
export default service

View File

@@ -0,0 +1,50 @@
Math.easeInOutQuad = function(t, b, c, d) {
t /= d / 2
if (t < 1) {
return c / 2 * t * t + b
}
t--
return -c / 2 * (t * (t - 2) - 1) + b
}
// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
var requestAnimFrame = (function() {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) }
})()
// because it's so fucking difficult to detect the scrolling element, just move them all
function move(amount) {
document.documentElement.scrollTop = amount
document.body.parentNode.scrollTop = amount
document.body.scrollTop = amount
}
function position() {
return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop
}
export function scrollTo(to, duration, callback) {
const start = position()
const change = to - start
const increment = 20
let currentTime = 0
duration = (typeof (duration) === 'undefined') ? 500 : duration
var animateScroll = function() {
// increment the time
currentTime += increment
// find the value with the quadratic in-out easing function
var val = Math.easeInOutQuad(currentTime, start, change, duration)
// move the document.body
move(val)
// do the animation unless its over
if (currentTime < duration) {
requestAnimFrame(animateScroll)
} else {
if (callback && typeof (callback) === 'function') {
// the animation is done so lets callback
callback()
}
}
}
animateScroll()
}

View File

@@ -0,0 +1,20 @@
/**
* Created by PanJiaChen on 16/11/18.
*/
/**
* @param {string} path
* @returns {Boolean}
*/
export function isExternal(path) {
return /^(https?:|mailto:|tel:)/.test(path)
}
/**
* @param {string} str
* @returns {Boolean}
*/
export function validUsername(str) {
const valid_map = ['admin', 'editor']
return valid_map.indexOf(str.trim()) >= 0
}

View File

@@ -0,0 +1,228 @@
<template>
<div class="wscn-http404-container">
<div class="wscn-http404">
<div class="pic-404">
<img class="pic-404__parent" src="@/assets/404_images/404.png" alt="404">
<img class="pic-404__child left" src="@/assets/404_images/404_cloud.png" alt="404">
<img class="pic-404__child mid" src="@/assets/404_images/404_cloud.png" alt="404">
<img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404">
</div>
<div class="bullshit">
<div class="bullshit__oops">OOPS!</div>
<div class="bullshit__info">All rights reserved
<a style="color:#20a0ff" href="https://wallstreetcn.com" target="_blank">wallstreetcn</a>
</div>
<div class="bullshit__headline">{{ message }}</div>
<div class="bullshit__info">Please check that the URL you entered is correct, or click the button below to return to the homepage.</div>
<a href="" class="bullshit__return-home">Back to home</a>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Page404',
computed: {
message() {
return 'The webmaster said that you can not enter this page...'
}
}
}
</script>
<style lang="scss" scoped>
.wscn-http404-container{
transform: translate(-50%,-50%);
position: absolute;
top: 40%;
left: 50%;
}
.wscn-http404 {
position: relative;
width: 1200px;
padding: 0 50px;
overflow: hidden;
.pic-404 {
position: relative;
float: left;
width: 600px;
overflow: hidden;
&__parent {
width: 100%;
}
&__child {
position: absolute;
&.left {
width: 80px;
top: 17px;
left: 220px;
opacity: 0;
animation-name: cloudLeft;
animation-duration: 2s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 1s;
}
&.mid {
width: 46px;
top: 10px;
left: 420px;
opacity: 0;
animation-name: cloudMid;
animation-duration: 2s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 1.2s;
}
&.right {
width: 62px;
top: 100px;
left: 500px;
opacity: 0;
animation-name: cloudRight;
animation-duration: 2s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 1s;
}
@keyframes cloudLeft {
0% {
top: 17px;
left: 220px;
opacity: 0;
}
20% {
top: 33px;
left: 188px;
opacity: 1;
}
80% {
top: 81px;
left: 92px;
opacity: 1;
}
100% {
top: 97px;
left: 60px;
opacity: 0;
}
}
@keyframes cloudMid {
0% {
top: 10px;
left: 420px;
opacity: 0;
}
20% {
top: 40px;
left: 360px;
opacity: 1;
}
70% {
top: 130px;
left: 180px;
opacity: 1;
}
100% {
top: 160px;
left: 120px;
opacity: 0;
}
}
@keyframes cloudRight {
0% {
top: 100px;
left: 500px;
opacity: 0;
}
20% {
top: 120px;
left: 460px;
opacity: 1;
}
80% {
top: 180px;
left: 340px;
opacity: 1;
}
100% {
top: 200px;
left: 300px;
opacity: 0;
}
}
}
}
.bullshit {
position: relative;
float: left;
width: 300px;
padding: 30px 0;
overflow: hidden;
&__oops {
font-size: 32px;
font-weight: bold;
line-height: 40px;
color: #1482f0;
opacity: 0;
margin-bottom: 20px;
animation-name: slideUp;
animation-duration: 0.5s;
animation-fill-mode: forwards;
}
&__headline {
font-size: 20px;
line-height: 24px;
color: #222;
font-weight: bold;
opacity: 0;
margin-bottom: 10px;
animation-name: slideUp;
animation-duration: 0.5s;
animation-delay: 0.1s;
animation-fill-mode: forwards;
}
&__info {
font-size: 13px;
line-height: 21px;
color: grey;
opacity: 0;
margin-bottom: 30px;
animation-name: slideUp;
animation-duration: 0.5s;
animation-delay: 0.2s;
animation-fill-mode: forwards;
}
&__return-home {
display: block;
float: left;
width: 110px;
height: 36px;
background: #1482f0;
border-radius: 100px;
text-align: center;
color: #ffffff;
opacity: 0;
font-size: 14px;
line-height: 36px;
cursor: pointer;
animation-name: slideUp;
animation-duration: 0.5s;
animation-delay: 0.3s;
animation-fill-mode: forwards;
}
@keyframes slideUp {
0% {
transform: translateY(60px);
opacity: 0;
}
100% {
transform: translateY(0);
opacity: 1;
}
}
}
}
</style>

View File

@@ -0,0 +1,204 @@
<template>
<div class="app-container">
<div class="filter-container">
<!-- <el-input v-model="listQuery.name" placeholder="Server 名称" style="width: 200px;" class="filter-item" />
<el-input v-model="listQuery.ip" placeholder="Server IP" style="width: 200px;" class="filter-item" />
<el-button class="filter-item" type="primary" icon="el-icon-search" plain @click="fetchData()">查询</el-button> -->
<el-button class="filter-item" type="primary" @click="handleCreate()">新建集群</el-button>
</div>
<el-table
v-loading="listLoading"
:data="list"
element-loading-text="Loading"
border
fit
highlight-current-row
>
<el-table-column label="集群名称" min-width="200" align="center">
<template slot-scope="scope">
{{ scope.row.name }}
</template>
</el-table-column>
<el-table-column label="ZK地址" min-width="300" align="center">
<template slot-scope="scope">
<span>{{ scope.row.zkHosts }}</span>
</template>
</el-table-column>
<el-table-column align="center" prop="created_at" label="操作" min-width="150">
<template slot-scope="scope">
<el-dropdown trigger="click">
<el-button type="primary" size="mini">
操作<i class="el-icon-arrow-down el-icon--right" />
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="handleConfig(scope.row)">主配置</el-dropdown-item>
<el-dropdown-item @click.native="handleUpdate(scope.row)">修改集群</el-dropdown-item>
<el-dropdown-item @click.native="handleDelete(scope.row)">删除集群</el-dropdown-item>
<el-dropdown-item @click.native="handleView(scope.row)">查看Server</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
<el-dialog :visible.sync="dialogFormVisible" :title="textMap[dialogStatus]" width="600px">
<el-form ref="dataForm" :rules="rules" :model="canalCluster" label-position="left" label-width="120px" style="width: 400px; margin-left:30px;">
<el-form-item label="集群名称" prop="name">
<el-input v-model="canalCluster.name" />
</el-form-item>
<el-form-item label="ZK地址" prop="zkHosts">
<el-input v-model="canalCluster.zkHosts" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取消</el-button>
<el-button type="primary" @click="dataOperation()">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { addCanalCluster, getCanalClusters, updateCanalCluster, deleteCanalCluster } from '@/api/canalCluster'
export default {
filters: {
statusFilter(status) {
const statusMap = {
'1': 'success',
'0': 'gray',
'-1': 'danger'
}
return statusMap[status]
},
statusLabel(status) {
const statusMap = {
'1': '启动',
'0': '停止',
'-1': '断开'
}
return statusMap[status]
}
},
data() {
return {
list: null,
listLoading: true,
listQuery: {
name: '',
ip: ''
},
dialogFormVisible: false,
textMap: {
create: '新建集群信息',
update: '修改集群信息'
},
canalCluster: {
id: null,
name: null,
zkHosts: null
},
rules: {
name: [{ required: true, message: '集群名称不能为空', trigger: 'change' }],
zkHosts: [{ required: true, message: 'zk地址不能为空', trigger: 'change' }]
},
dialogStatus: 'create'
}
},
created() {
this.fetchData()
},
methods: {
fetchData() {
this.listLoading = true
getCanalClusters(this.listQuery).then(res => {
this.list = res.data
}).finally(() => {
this.listLoading = false
})
},
resetModel() {
this.canalCluster = {
id: null,
name: null,
zkHosts: null
}
},
handleCreate() {
this.resetModel()
this.dialogStatus = 'create'
this.dialogFormVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
dataOperation() {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
if (this.dialogStatus === 'create') {
addCanalCluster(this.canalCluster).then(res => {
this.operationRes(res)
})
}
if (this.dialogStatus === 'update') {
updateCanalCluster(this.canalCluster).then(res => {
this.operationRes(res)
})
}
}
})
},
operationRes(res) {
if (res.data === 'success') {
this.fetchData()
this.dialogFormVisible = false
this.$message({
message: this.textMap[this.dialogStatus] + '成功',
type: 'success'
})
} else {
this.$message({
message: this.textMap[this.dialogStatus] + '失败',
type: 'error'
})
}
},
handleView(row) {
this.$router.push('/canalServer/nodeServers?clusterId=' + row.id)
},
handleConfig(row) {
this.$router.push('/canalServer/nodeServer/config?clusterId=' + row.id)
},
handleUpdate(row) {
this.resetModel()
this.canalCluster = Object.assign({}, row)
this.dialogStatus = 'update'
this.dialogFormVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
handleDelete(row) {
this.$confirm('删除集群信息会导致服务停止', '确定删除集群信息', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteCanalCluster(row.id).then((res) => {
if (res.data === 'success') {
this.fetchData()
this.$message({
message: '删除集群信息成功',
type: 'success'
})
} else {
this.$message({
message: '删除集群信息失败',
type: 'error'
})
}
})
})
}
}
}
</script>

View File

@@ -0,0 +1,120 @@
<template>
<div>
<el-form ref="form" :model="form">
<div style="padding-left: 10px;padding-top: 20px;">
<el-form-item>
{{ form.name }}&nbsp;&nbsp;&nbsp;&nbsp;
<el-button type="primary" @click="onSubmit">保存</el-button>
<el-button type="warning" @click="onCancel">重置</el-button>
<el-button type="success" @click="onLoadTemplate">载入模板</el-button>
<el-button type="info" @click="onBack">返回</el-button>
</el-form-item>
</div>
<editor v-model="form.content" lang="properties" theme="chrome" width="100%" :height="800" @init="editorInit" />
</el-form>
</div>
</template>
<script>
import { getCanalConfig, updateCanalConfig, getTemplateConfig } from '@/api/canalConfig'
export default {
components: {
editor: require('vue2-ace-editor')
},
data() {
return {
form: {
id: null,
name: '',
content: '',
serverId: null,
clusterId: null
}
}
},
created() {
this.loadCanalConfig()
},
methods: {
editorInit() {
require('brace/ext/language_tools')
require('brace/mode/html')
require('brace/mode/yaml')
require('brace/mode/properties')
require('brace/mode/javascript')
require('brace/mode/less')
require('brace/theme/chrome')
require('brace/snippets/javascript')
},
loadCanalConfig() {
let clusterId = 0
let serverId = 0
if (this.$route.query.clusterId) {
clusterId = this.$route.query.clusterId
} else if (this.$route.query.serverId) {
serverId = this.$route.query.serverId
}
getCanalConfig(clusterId, serverId).then(response => {
const data = response.data
this.form.id = data.id
this.form.name = data.name
this.form.content = data.content
this.form.serverId = this.$route.query.serverId
this.form.clusterId = this.$route.query.clusterId
})
},
onSubmit() {
if (this.form.content === null || this.form.content === '') {
this.$message({
message: '配置内容不能为空',
type: 'error'
})
return
}
this.$confirm(
'修改主配置可能会导致Server重启,是否继续?',
'确定修改',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
updateCanalConfig(this.form).then(response => {
if (response.data === 'success') {
this.$message({
message: '保存成功',
type: 'success'
})
this.loadCanalConfig()
} else {
this.$message({
message: '保存失败',
type: 'error'
})
}
})
})
},
onCancel() {
this.loadCanalConfig()
},
onBack() {
history.go(-1)
},
onLoadTemplate() {
getTemplateConfig().then(res => {
this.form.content = res.data
})
}
}
}
</script>
<style scoped>
.line{
text-align: center;
}
</style>

View File

@@ -0,0 +1,228 @@
<template>
<div class="app-container">
<div class="filter-container">
<el-input v-model="listQuery.name" placeholder="Instance 名称" style="width: 200px;" class="filter-item" />
<el-select v-model="listQuery.clusterServerId" placeholder="所属集群/主机" class="filter-item">
<el-option key="" label="所属集群/主机" value="" />
<el-option-group v-for="group in options" :key="group.label" :label="group.label">
<el-option v-for="item in group.options" :key="item.value" :label="item.label" :value="item.value" />
</el-option-group>
</el-select>
<el-button class="filter-item" type="primary" icon="el-icon-search" plain @click="queryData()">查询</el-button>
&nbsp;&nbsp;
<el-button class="filter-item" type="primary" @click="handleCreate()">新建 Instance</el-button>
<el-button class="filter-item" type="info" @click="fetchData()">刷新列表</el-button>
</div>
<el-table
v-loading="listLoading"
:data="list"
element-loading-text="Loading"
border
fit
highlight-current-row
>
<el-table-column label="Instance 名称" min-width="200" align="center">
<template slot-scope="scope">
{{ scope.row.name }}
</template>
</el-table-column>
<el-table-column label="所属集群" min-width="200" align="center">
<template slot-scope="scope">
<span v-if="scope.row.canalCluster !== null">
{{ scope.row.canalCluster.name }}
</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="所属主机" min-width="200" align="center">
<template slot-scope="scope">
<span v-if="scope.row.nodeServer !== null">
{{ scope.row.nodeServer.name }}
</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column class-name="status-col" label="状态" min-width="150" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.runningStatus | statusFilter">{{ scope.row.runningStatus | statusLabel }}</el-tag>
</template>
</el-table-column>
<el-table-column label="修改时间" min-width="200" align="center">
<template slot-scope="scope">
{{ scope.row.modifiedTime }}
</template>
</el-table-column>
<el-table-column align="center" prop="created_at" label="操作" min-width="150">
<template slot-scope="scope">
<el-dropdown trigger="click">
<el-button type="primary" size="mini">
操作<i class="el-icon-arrow-down el-icon--right" />
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="handleUpdate(scope.row)">修改</el-dropdown-item>
<el-dropdown-item @click.native="handleDelete(scope.row)">删除</el-dropdown-item>
<el-dropdown-item @click.native="handleStart(scope.row)">启动</el-dropdown-item>
<el-dropdown-item @click.native="handleStop(scope.row)">停止</el-dropdown-item>
<el-dropdown-item @click.native="handleLog(scope.row)">日志</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
<pagination v-show="count>0" :total="count" :page.sync="listQuery.page" :limit.sync="listQuery.size" @pagination="fetchData()" />
</div>
</template>
<script>
import { getCanalInstances, deleteCanalInstance, instanceStatus } from '@/api/canalInstance'
import Pagination from '@/components/Pagination'
import { getClustersAndServers } from '@/api/canalCluster'
export default {
components: { Pagination },
filters: {
statusFilter(status) {
const statusMap = {
'1': 'success',
'0': 'gray'
}
return statusMap[status]
},
statusLabel(status) {
const statusMap = {
'1': '启动',
'0': '停止'
}
return statusMap[status]
}
},
data() {
return {
list: null,
listLoading: true,
dialogFormVisible: false,
nodeServices: [],
count: 0,
options: [],
listQuery: {
name: '',
clusterServerId: '',
page: 1,
size: 20
},
currentId: null,
rules: {
id: [{ required: true, message: '请选择运行Server', trigger: 'change' }]
}
}
},
created() {
getClustersAndServers().then((res) => {
this.options = res.data
})
this.fetchData()
},
methods: {
queryData() {
this.listQuery.page = 1
this.fetchData()
},
fetchData() {
this.listLoading = true
getCanalInstances(this.listQuery).then(res => {
this.list = res.data.items
this.count = res.data.count
}).finally(() => {
this.listLoading = false
})
},
handleCreate() {
this.$router.push('/canalServer/canalInstance/add')
},
handleUpdate(row) {
this.$router.push('/canalServer/canalInstance/modify?id=' + row.id)
},
handleDelete(row) {
this.$confirm('删除Instance配置会导致停止', '确定删除Instance信息', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteCanalInstance(row.id).then((res) => {
if (res.data === 'success') {
this.fetchData()
this.$message({
message: '删除Instance信息成功',
type: 'success'
})
} else {
this.$message({
message: '删除Instance信息失败',
type: 'error'
})
}
})
})
},
handleStart(row) {
// if (row.runningStatus === '1') {
// this.$message({ message: '当前Instance已处于启动状态!', type: 'error' })
// return
// }
this.$confirm('启动Instance: ' + row.name, '确定启动Instance服务', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
instanceStatus(row.id, 'start').then((res) => {
if (res.data) {
this.fetchData()
this.$message({
message: '启动成功, 稍后请刷新列表查看状态',
type: 'success'
})
} else {
this.$message({
message: '启动Instance出现异常',
type: 'error'
})
}
})
})
},
handleStop(row) {
// if (row.runningStatus === '0') {
// this.$message({ message: '当前Instance已处于停止状态!', type: 'error' })
// return
// }
this.$confirm('停止Instance: ' + row.name, '确定停止Instance服务', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
instanceStatus(row.id, 'stop').then((res) => {
if (res.data) {
this.fetchData()
this.$message({
message: '停止成功, 稍后请刷新列表查看状态',
type: 'success'
})
} else {
this.$message({
message: '停止Instance出现异常',
type: 'error'
})
}
})
})
},
handleLog(row) {
if (row.nodeId === null) {
this.$message({ message: '当前Instance不是启动状态,无法查看日志', type: 'warning' })
return
}
this.$router.push('canalInstance/log?id=' + row.id + '&nodeId=' + row.nodeServer.id)
}
}
}
</script>

View File

@@ -0,0 +1,118 @@
<template>
<div>
<el-form ref="form" :model="form">
<div class="filter-container" style="padding-left: 10px;padding-top: 20px;">
<el-input v-model="form.name" placeholder="Instance名称" style="width: 200px;" class="filter-item" />
<el-select v-model="form.clusterServerId" placeholder="所属集群/主机" class="filter-item">
<el-option-group v-for="group in options" :key="group.label" :label="group.label">
<el-option v-for="item in group.options" :key="item.value" :label="item.label" :value="item.value" />
</el-option-group>
</el-select>
<el-button class="filter-item" type="primary" @click="onSubmit">保存</el-button>
<el-button class="filter-item" type="success" @click="onLoadTemplate">载入模板</el-button>
<el-button class="filter-item" type="info" @click="onBack">返回</el-button>
</div>
<editor v-model="form.content" lang="properties" theme="chrome" width="100%" :height="800" @init="editorInit" />
</el-form>
</div>
</template>
<script>
import { addCanalInstance, getTemplateInstance } from '@/api/canalInstance'
import { getClustersAndServers } from '@/api/canalCluster'
export default {
components: {
editor: require('vue2-ace-editor')
},
data() {
return {
options: [],
form: {
name: '',
content: '',
clusterServerId: ''
}
}
},
created() {
getClustersAndServers().then((res) => {
this.options = res.data
})
},
methods: {
editorInit() {
require('brace/ext/language_tools')
require('brace/mode/html')
require('brace/mode/yaml')
require('brace/mode/properties')
require('brace/mode/javascript')
require('brace/mode/less')
require('brace/theme/chrome')
require('brace/snippets/javascript')
},
onSubmit() {
if (this.form.name === '') {
this.$message({
message: '请输入Instance名称',
type: 'error'
})
return
}
if (this.form.clusterServerId === '') {
this.$message({
message: '请选择所属集群/主机',
type: 'error'
})
return
}
if (this.form.content === null || this.form.content === '') {
this.$message({
message: '请输入配置内容',
type: 'error'
})
return
}
this.$confirm(
'确定新建',
'确定新建',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
addCanalInstance(this.form).then(response => {
if (response.data === 'success') {
this.$message({
message: '新建成功',
type: 'success'
})
this.$router.push('/canalServer/canalInstances')
} else {
this.$message({
message: '新建失败',
type: 'error'
})
}
})
})
},
onBack() {
history.go(-1)
},
onLoadTemplate() {
getTemplateInstance().then(res => {
this.form.content = res.data
})
}
}
}
</script>
<style scoped>
.line{
text-align: center;
}
</style>

View File

@@ -0,0 +1,53 @@
<template>
<div>
<el-form ref="form" :model="form">
<div style="padding-left: 10px;padding-right: 10px;padding-top: 20px;">
<el-form-item>
{{ form.instance }}&nbsp;&nbsp;&nbsp;&nbsp;
<el-button type="primary" @click="onRefresh">刷新</el-button>
<el-button type="info" @click="onBack">返回</el-button>
</el-form-item>
<el-input v-model="form.desc" :rows="35" :readonly="'readonly'" type="textarea" />
</div>
</el-form>
</div>
</template>
<script>
import { instanceLog } from '@/api/canalInstance'
export default {
data() {
return {
form: {
instance: '',
desc: ''
}
}
},
created() {
this.fetchData()
},
methods: {
fetchData() {
instanceLog(this.$route.query.id, this.$route.query.nodeId).then(res => {
this.form.instance = res.data.instance + '.log'
this.form.desc = res.data.log
})
},
onRefresh() {
this.fetchData()
},
onBack() {
history.go(-1)
}
}
}
</script>
<style scoped>
.line{
text-align: center;
}
</style>

View File

@@ -0,0 +1,108 @@
<template>
<div>
<el-form ref="form" :model="form">
<div style="padding-left: 10px;padding-top: 20px;">
<el-form-item>
{{ form.name }}&nbsp;&nbsp;&nbsp;&nbsp;
<el-select v-model="form.clusterServerId" placeholder="所属集群/主机" class="filter-item">
<el-option-group v-for="group in options" :key="group.label" :label="group.label">
<el-option v-for="item in group.options" :key="item.value" :label="item.label" :value="item.value" />
</el-option-group>
</el-select>
<el-button type="primary" @click="onSubmit">修改</el-button>
<el-button type="warning" @click="onCancel">重置</el-button>
<el-button type="info" @click="onBack">返回</el-button>
</el-form-item>
</div>
<editor v-model="form.content" lang="properties" theme="chrome" width="100%" :height="800" @init="editorInit" />
</el-form>
</div>
</template>
<script>
import { canalInstanceDetail, updateCanalInstance } from '@/api/canalInstance'
import { getClustersAndServers } from '@/api/canalCluster'
export default {
components: {
editor: require('vue2-ace-editor')
},
data() {
return {
options: [],
form: {
id: null,
name: '',
content: '',
clusterServerId: ''
}
}
},
created() {
this.loadCanalConfig()
getClustersAndServers().then((res) => {
this.options = res.data
})
},
methods: {
editorInit() {
require('brace/ext/language_tools')
require('brace/mode/html')
require('brace/mode/yaml')
require('brace/mode/properties')
require('brace/mode/javascript')
require('brace/mode/less')
require('brace/theme/chrome')
require('brace/snippets/javascript')
},
loadCanalConfig() {
canalInstanceDetail(this.$route.query.id).then(response => {
const data = response.data
this.form.id = data.id
this.form.name = data.name + '/instance.properties'
this.form.content = data.content
this.form.clusterServerId = data.clusterServerId
})
},
onSubmit() {
this.$confirm(
'修改Instance配置可能会导致重启,是否继续?',
'确定修改',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
updateCanalInstance(this.form).then(response => {
if (response.data === 'success') {
this.$message({
message: '修改成功',
type: 'success'
})
this.loadCanalConfig()
} else {
this.$message({
message: '修改失败',
type: 'error'
})
}
})
})
},
onCancel() {
this.loadCanalConfig()
},
onBack() {
history.go(-1)
}
}
}
</script>
<style scoped>
.line{
text-align: center;
}
</style>

View File

@@ -0,0 +1,51 @@
<template>
<div>
<el-form ref="form" :model="form">
<div style="padding-left: 10px;padding-right: 10px;padding-top: 20px;">
<el-form-item>
canal.log&nbsp;&nbsp;&nbsp;&nbsp;
<el-button type="primary" @click="onRefresh">刷新</el-button>
<el-button type="info" @click="onBack">返回</el-button>
</el-form-item>
<el-input v-model="form.desc" :rows="35" :readonly="'readonly'" type="textarea" />
</div>
</el-form>
</div>
</template>
<script>
import { nodeServerLog } from '@/api/nodeServer'
export default {
data() {
return {
form: {
desc: ''
}
}
},
created() {
this.fetchData()
},
methods: {
fetchData() {
nodeServerLog(this.$route.query.id).then(res => {
this.form.desc = res.data
})
},
onRefresh() {
this.fetchData()
},
onBack() {
history.go(-1)
}
}
}
</script>
<style scoped>
.line{
text-align: center;
}
</style>

View File

@@ -0,0 +1,459 @@
<template>
<div class="app-container">
<div class="filter-container">
<!--<el-input v-model="listQuery.name" placeholder="Server 名称" style="width: 200px;" class="filter-item" />-->
<el-select v-model="listQuery.clusterId" placeholder="所属集群" class="filter-item">
<el-option key="" label="所属集群" value="" />
<el-option key="-1" label="单机" value="-1" />
<el-option v-for="item in canalClusters" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
<el-input v-model="listQuery.ip" placeholder="Server IP" style="width: 200px;" class="filter-item" />
<el-button class="filter-item" type="primary" icon="el-icon-search" plain @click="queryData()">查询</el-button>
<el-button class="filter-item" type="primary" @click="handleCreate()">新建Server</el-button>
<el-button class="filter-item" type="info" @click="fetchData()">刷新列表</el-button>
</div>
<el-table
v-loading="listLoading"
:data="list"
element-loading-text="Loading"
border
fit
highlight-current-row
>
<el-table-column label="所属集群" min-width="200" align="center">
<template slot-scope="scope">
<span v-if="scope.row.canalCluster !== null">
{{ scope.row.canalCluster.name }}
</span>
<span v-else>
-
</span>
</template>
</el-table-column>
<el-table-column label="Server 名称" min-width="200" align="center">
<template slot-scope="scope">
{{ scope.row.name }}
</template>
</el-table-column>
<el-table-column label="Server IP" min-width="200" align="center">
<template slot-scope="scope">
<span>{{ scope.row.ip }}</span>
</template>
</el-table-column>
<el-table-column label="admin 端口" min-width="100" align="center">
<template slot-scope="scope">
{{ scope.row.adminPort }}
</template>
</el-table-column>
<el-table-column label="tcp 端口" min-width="100" align="center">
<template slot-scope="scope">
{{ scope.row.tcpPort }}
</template>
</el-table-column>
<el-table-column label="metric 端口" min-width="100" align="center">
<template slot-scope="scope">
{{ scope.row.metricPort }}
</template>
</el-table-column>
<el-table-column class-name="status-col" label="状态" min-width="150" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.status | statusFilter">{{ scope.row.status | statusLabel }}</el-tag>
</template>
</el-table-column>
<el-table-column align="center" prop="created_at" label="操作" min-width="150">
<template slot-scope="scope">
<el-dropdown trigger="click">
<el-button type="primary" size="mini">
操作<i class="el-icon-arrow-down el-icon--right" />
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="handleConfig(scope.row)">配置</el-dropdown-item>
<el-dropdown-item @click.native="handleUpdate(scope.row)">修改</el-dropdown-item>
<el-dropdown-item @click.native="handleDelete(scope.row)">删除</el-dropdown-item>
<el-dropdown-item @click.native="handleStart(scope.row)">启动</el-dropdown-item>
<el-dropdown-item @click.native="handleStop(scope.row)">停止</el-dropdown-item>
<el-dropdown-item @click.native="handleInstances(scope.row)">详情</el-dropdown-item>
<el-dropdown-item @click.native="handleLog(scope.row)">日志</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
<pagination v-show="count>0" :total="count" :page.sync="listQuery.page" :limit.sync="listQuery.size" @pagination="fetchData()" />
<el-dialog :visible.sync="dialogFormVisible" :title="textMap[dialogStatus]" width="600px">
<el-form ref="dataForm" :rules="rules" :model="nodeModel" label-position="left" label-width="120px" style="width: 400px; margin-left:30px;">
<el-form-item label="所属集群" prop="clusterId">
<el-select v-if="dialogStatus === 'create'" v-model="nodeModel.clusterId" placeholder="选择所属集群">
<el-option key="" label="单机" value="" />
<el-option v-for="item in canalClusters" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
<el-select v-else v-model="nodeModel.clusterId" placeholder="选择所属集群" disabled="disabled">
<el-option key="" label="单机" value="" />
<el-option v-for="item in canalClusters" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="Server 名称" prop="name">
<el-input v-model="nodeModel.name" />
</el-form-item>
<el-form-item label="Server IP" prop="ip">
<el-input v-model="nodeModel.ip" />
</el-form-item>
<el-form-item label="admin 端口" prop="adminPort">
<el-input v-model="nodeModel.adminPort" placeholder="11110" type="number" />
</el-form-item>
<el-form-item label="tcp 端口" prop="tcpPort">
<el-input v-model="nodeModel.tcpPort" placeholder="11111" type="number" />
</el-form-item>
<el-form-item label="metric 端口" prop="metricPort">
<el-input v-model="nodeModel.metricPort" placeholder="11112" type="number" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取消</el-button>
<el-button type="primary" @click="dataOperation()">确定</el-button>
</div>
</el-dialog>
<el-dialog :visible.sync="dialogInstances" title="instance 列表" width="800px">
<div class="filter-container">
<el-button class="filter-item" type="info" @click="activeInstances()">刷新列表</el-button>
</div>
<el-table
v-loading="listLoading2"
:data="instanceList"
element-loading-text="Loading"
border
fit
highlight-current-row
>
<el-table-column label="Instance 名称" min-width="200" align="center">
<template slot-scope="scope">
{{ scope.row.name }}
</template>
</el-table-column>
<el-table-column label="状态" min-width="200" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.runningStatus | statusFilter">{{ scope.row.runningStatus | statusLabel }}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" min-width="200" align="center">
<template slot-scope="scope">
<el-dropdown trigger="click">
<el-button type="primary" size="mini">
操作<i class="el-icon-arrow-down el-icon--right" />
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="handleStartInstance(scope.row)">启动</el-dropdown-item>
<el-dropdown-item @click.native="handleStopInstance(scope.row)">停止</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
</el-dialog>
</div>
</template>
<script>
import { addNodeServer, getNodeServers, updateNodeServer, deleteNodeServer, startNodeServer, stopNodeServer } from '@/api/nodeServer'
import { getActiveInstances, stopInstance, startInstance } from '@/api/canalInstance'
import { getCanalClusters } from '@/api/canalCluster'
import Pagination from '@/components/Pagination'
export default {
components: { Pagination },
filters: {
statusFilter(status) {
const statusMap = {
'1': 'success',
'0': 'gray',
'-1': 'danger'
}
return statusMap[status]
},
statusLabel(status) {
const statusMap = {
'1': '启动',
'0': '停止',
'-1': '断开'
}
return statusMap[status]
}
},
data() {
return {
list: null,
instanceList: null,
listLoading: true,
listLoading2: true,
serverIdTmp: null,
canalClusters: [],
count: 0,
listQuery: {
name: '',
ip: '',
clusterId: null,
page: 1,
size: 20
},
dialogFormVisible: false,
dialogInstances: false,
textMap: {
create: '新建Server信息',
update: '修改Server信息'
},
nodeModel: {
id: undefined,
clusterId: null,
name: null,
ip: null,
adminPort: 11110,
tcpPort: 11111,
metricPort: 11112
},
rules: {
name: [{ required: true, message: 'Server 名称不能为空', trigger: 'change' }],
ip: [{ required: true, message: 'Server IP不能为空', trigger: 'change' }],
adminPort: [{ required: true, message: 'Server admin端口不能为空', trigger: 'change' }]
},
dialogStatus: 'create'
}
},
// { min: 2, max: 5, message: '长度在 2 到 5 个字符', trigger: 'change' }
created() {
getCanalClusters().then((res) => {
this.canalClusters = res.data
})
if (this.$route.query.clusterId) {
try {
this.listQuery.clusterId = Number(this.$route.query.clusterId)
} catch (e) {
console.log(e)
}
}
this.fetchData()
},
methods: {
fetchData() {
this.listLoading = true
getNodeServers(this.listQuery).then(res => {
this.list = res.data.items
this.count = res.data.count
}).finally(() => {
this.listLoading = false
})
},
queryData() {
this.listQuery.page = 1
this.fetchData()
},
resetModel() {
this.nodeModel = {
id: undefined,
clusterId: null,
name: null,
ip: null,
adminPort: null,
tcpPort: null,
metricPort: null
}
},
handleCreate() {
this.resetModel()
this.dialogStatus = 'create'
this.dialogFormVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
handleInstances(row) {
this.serverIdTmp = row.id
this.activeInstances()
},
activeInstances() {
this.listLoading2 = true
this.dialogInstances = true
getActiveInstances(this.serverIdTmp).then(res => {
this.instanceList = res.data
}).finally(() => {
this.listLoading2 = false
})
},
dataOperation() {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
if (this.dialogStatus === 'create') {
addNodeServer(this.nodeModel).then(res => {
this.operationRes(res)
})
}
if (this.dialogStatus === 'update') {
updateNodeServer(this.nodeModel).then(res => {
this.operationRes(res)
})
}
}
})
},
operationRes(res) {
if (res.data === 'success') {
this.fetchData()
this.dialogFormVisible = false
this.$message({
message: this.textMap[this.dialogStatus] + '成功',
type: 'success'
})
} else {
this.$message({
message: this.textMap[this.dialogStatus] + '失败',
type: 'error'
})
}
},
handleConfig(row) {
if (row.canalCluster !== null) {
this.$message({ message: '集群模式Server不允许单独变更配置,请在集群配置变更', type: 'error' })
return
}
this.$router.push('/canalServer/nodeServer/config?serverId=' + row.id)
},
handleUpdate(row) {
this.resetModel()
this.nodeModel = Object.assign({}, row)
this.dialogStatus = 'update'
this.dialogFormVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
handleDelete(row) {
this.$confirm('删除Server信息会导致节点服务停止', '确定删除Server信息', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteNodeServer(row.id).then((res) => {
if (res.data === 'success') {
this.fetchData()
this.$message({
message: '删除Server信息成功',
type: 'success'
})
} else {
this.$message({
message: '删除Server信息失败',
type: 'error'
})
}
})
})
},
handleStart(row) {
if (row.status !== '0') {
this.$message({ message: '当前Server不是停止状态,无法启动', type: 'error' })
return
}
this.$confirm('启动Server服务', '确定启动Server服务', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
startNodeServer(row.id).then((res) => {
if (res.data) {
this.fetchData()
this.$message({
message: '启动成功',
type: 'success'
})
} else {
this.$message({
message: '启动Server服务出现异常',
type: 'error'
})
}
})
})
},
handleStop(row) {
if (row.status !== '1') {
this.$message({ message: '当前Server不是启动状态,无法停止', type: 'error' })
return
}
this.$confirm('停止Server服务会导致所有Instance都停止服务', '确定停止Server服务', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
stopNodeServer(row.id).then((res) => {
if (res.data) {
this.fetchData()
this.$message({
message: '停止成功',
type: 'success'
})
} else {
this.$message({
message: '停止Server服务出现异常',
type: 'error'
})
}
})
})
},
handleLog(row) {
this.$router.push('nodeServer/log?id=' + row.id)
},
handleStartInstance(row) {
if (row.runningStatus !== '0') {
this.$message({ message: '当前Instance不是停止状态,无法启动', type: 'error' })
return
}
this.$confirm('启动Instance服务', '确定启动Instance服务', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
startInstance(row.id, this.serverIdTmp).then((res) => {
if (res.data) {
this.activeInstances()
this.$message({
message: '启动成功, 稍后请刷新列表查看状态',
type: 'success'
})
} else {
this.$message({
message: '启动Instance服务出现异常',
type: 'error'
})
}
})
})
},
handleStopInstance(row) {
if (row.runningStatus !== '1') {
this.$message({ message: '当前Instance不是运行状态,无法停止', type: 'error' })
return
}
this.$confirm('集群模式下停止实例其它主机将会抢占执行该实例', '停止 Instance 服务', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
stopInstance(row.id, this.serverIdTmp).then((res) => {
if (res.data) {
this.activeInstances()
this.$message({
message: '停止成功, 稍后请刷新列表查看状态',
type: 'success'
})
} else {
this.$message({
message: '停止Instance服务出现异常',
type: 'error'
})
}
})
})
}
}
}
</script>

Some files were not shown because too many files have changed in this diff Show More