Compare commits

..

149 Commits

Author SHA1 Message Date
胡俊 08657b90b3
fix #https://github.com/alibaba/nacos/issues/12478 (#344) 2024-11-04 09:26:54 +08:00
Lemon eaf15a6e6e
Fix using dataids field causes NullPointerException (#321) 2023-12-29 20:49:09 +08:00
胡俊 5a97a9dd6b
2.1.0-RC 2023-12-06 17:21:07 +08:00
胡俊 6c29062a1c
0.3.0-RC 2023-12-03 13:31:58 +08:00
胡俊 a5aa9f70bb
Summer ospp#10375 (#312)
* [ISSUE #10375] Support springboot3 and native-image (#306)

* [ISSUE #10375] Support SpringBoot3

* [ISSUE #10375] Support native-image

* [ISSUE #10375] Update document and add AOT sample (#307)

Update document and add AOT sample

---------

Co-authored-by: SuperZ1999 <34301918+SuperZ1999@users.noreply.github.com>
2023-12-03 11:25:29 +08:00
胡俊 82caa209b3
add user guide link 2023-07-15 15:12:55 +08:00
Guocheng Tang 71db41f853
[ISSUE #293] Fixed yaml configuration not working (#293)
Fixed configuration not working
2023-07-06 20:23:14 +08:00
slatonwu a5ba72ac01
支持修改context-path (#290)
Co-authored-by: wuhui <wuhui@88.com>
2023-07-01 14:55:51 +08:00
slatonwu df0f68fcfa
增加 nacos.config.bootstrap.snapshot-enable 配置,用于关闭,开启是否保存快照 (#295)
Co-authored-by: wuhui <wuhui@88.com>
2023-07-01 14:54:53 +08:00
HPxianliru 7144598c21
1 solve startup project logger error,not set nacos.config.data-ids value #174 (#175) 2023-06-04 12:00:21 +08:00
chenhao26 c080c91c15
add some junit test (#262)
add some junit test
2022-08-15 19:25:31 +08:00
realJackSun 8b2621bc29
Add the <configuration> to fix the javadoc problem (#259) 2022-07-21 12:10:55 +08:00
realJackSun 6b626f364c Change to version 0.2.12 2022-07-21 11:39:10 +08:00
qyqcswill 6771d1b311
fix security issue of exposing ak ,sk in log print. (#257) 2022-07-21 10:54:22 +08:00
yanglulu 008ae0bce7
[ISSUE#226] yaml multi profiles support (#227)
* yaml multi profiles support

* add License

* yaml multi profiles support

* fix: more unit test
2022-06-30 16:52:49 +08:00
胡俊 a9d0ea104a
changer version to 0.2.11 (#250)
Co-authored-by: hujun3 <hujun3@xiaomi.com>
2022-06-24 13:00:17 +08:00
dependabot[bot] c682961079
chore(deps): bump junit from 4.12 to 4.13.1 in /nacos-spring-boot-parent (#235)
Bumps [junit](https://github.com/junit-team/junit4) from 4.12 to 4.13.1.
- [Release notes](https://github.com/junit-team/junit4/releases)
- [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.12.md)
- [Commits](https://github.com/junit-team/junit4/compare/r4.12...r4.13.1)

---
updated-dependencies:
- dependency-name: junit:junit
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-28 14:19:53 +08:00
dependabot[bot] af106fc5da
chore(deps): bump spring-boot-starter-web (#236)
Bumps [spring-boot-starter-web](https://github.com/spring-projects/spring-boot) from 2.1.6.RELEASE to 2.5.12.
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v2.1.6.RELEASE...v2.5.12)

---
updated-dependencies:
- dependency-name: org.springframework.boot:spring-boot-starter-web
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-28 14:14:53 +08:00
Oliver 3e50f33fe7
Fix printing log style (#240) 2022-05-13 09:42:00 +08:00
liaochuntao b1a19f679f
Merge pull request #238 from hujun-w-2/fix_log_auto
[ISSUE#242]modify log overload method
2022-05-11 11:30:35 +08:00
realJackSun e5ada95281 Change version to 0.2.11-beta 2022-05-06 12:04:09 +08:00
liaochuntao 3ecc302443
Merge pull request #239 from Oliverwqcwrw/master-replace-deprecated-method-1
Replace deprecated method to officially recommended api
2022-04-30 11:26:08 +08:00
liaochuntao 04e84c2b42
Merge pull request #243 from chenhao26-nineteen/buildNacosProperties_method_enhance_readability
Increase method readability
2022-04-30 11:25:46 +08:00
hujun3 02236568b4 adapt test 2022-04-29 19:42:47 +08:00
hujun3 b6da64e902 modify log overload method 2022-04-29 14:34:53 +08:00
chaos f0cc777109 Increase method readability 2022-04-28 14:58:38 +08:00
hujun 35e9c3e7c1 dependency nacos-client 2.1.0 2022-04-28 09:54:44 +08:00
hujun 40035fa032 Merge remote-tracking branch 'origin/fix_log_auto' into fix_log_auto
# Conflicts:
#	nacos-config-spring-boot-autoconfigure/src/main/java/com/alibaba/boot/nacos/config/util/log/LogAutoFreshProcess.java
2022-04-27 23:54:56 +08:00
hujun 2d257777c2 Optimize configuration reset logic. 2022-04-27 23:52:51 +08:00
hujun3 f9efddfb44 Optimize configuration reset logic. 2022-04-27 23:28:57 +08:00
hujun ca9a90543a Optimize configuration reset logic. 2022-04-27 23:23:36 +08:00
hujun 979c01702d Optimize configuration reset logic. 2022-04-27 23:20:19 +08:00
hujun a09746f41e Optimize configuration reset logic. 2022-04-27 23:15:42 +08:00
Oliver bfecd49e33
Update modifiers order (#241) 2022-04-26 09:59:28 +08:00
hujun3 cd810f4d25 启动依然沿用springboot 2022-04-25 13:31:41 +08:00
hujun3 aec14871ca fix nacos logs bug 2022-04-25 13:00:43 +08:00
Oliver 9a27a58a00 Replace deprecated method to officially recommended api 2022-04-25 10:33:14 +08:00
hujun3 e725f83cdc fix nacos logs bug 2022-04-24 14:34:40 +08:00
hujun3 d1575460b8 fix nacos logs bug 2022-04-22 22:25:38 +08:00
hujun3 b2649223da fix nacos logs bug 2022-04-22 22:11:30 +08:00
hujun3 1ef681c7d6 fix nacos logs bug 2022-04-22 21:47:48 +08:00
胡俊 e54e0cdd0d
Feature change version (#234)
* change springboot version

* change springboot version

Co-authored-by: hujun3 <hujun3@xiaomi.com>
2022-03-21 17:47:15 +08:00
胡俊 a8d6a80dd8
[ISSUEhttps://github.com/alibaba/nacos/issues/6999]Managed log framework (#228)
* Managed log framework

* Managed log framework-update

* Managed log framework -update

Co-authored-by: hujun3 <hujun3@xiaomi.com>
2022-03-14 09:52:08 +08:00
liaochuntao dbde2edc24
Merge pull request #230 from onewe/fix/issue-229
[ISSUE#229] add config type default value
2022-03-10 21:45:25 +08:00
liaochuntao 147829ac05
Merge pull request #232 from shouyuwang/master
fix: nacos property arg bug
2022-03-07 14:30:10 +08:00
王守钰 a981cc9de9 fix nacos property arg bug 2022-03-04 22:45:52 +08:00
onewe 0bf34babc6 [ISSUE#229] add config type default value
Close#229
2022-02-18 10:29:27 +08:00
胡俊 3e70665970
[ISSUE#223]update nacos-client version #223 (#224)
* update nacos-client version #223

* .
2022-01-24 16:16:53 +08:00
liaochuntao f9c1d281ad
Merge pull request #225 from hujun-w-2/develop-bug#215
[ISSUE#215]fix bug(When a key is deleted from the map attribute of the configuration center, it is not actually deleted in the business system)
2022-01-21 12:02:05 +08:00
hujun 03ec22f997 fix bug#215 2022-01-16 13:11:14 +08:00
胡俊 ed5843c16b
Code optimization (#220)
Co-authored-by: hujun3 <Hujun123>
2021-12-13 16:00:27 +08:00
zhanyao f401521964
去除spring boot 2.4以上版本ConfigurationBeanFactoryMetadata不兼容代码 (#194) 2021-12-13 11:45:03 +08:00
realJackSun 1bdd5a2e1a
Upgrade to 0.2.10: upgrade the nacos-spring dependency to 1.1.1, nacos-client dependency version to 2.0.2 (#206) 2021-07-19 17:57:23 +08:00
yanlinly b2fb611d4c
Merge pull request #205 from realJackSun/0.2.8-bugfix
release 0.2.8-bugfix, Fix the thread-safety problem in NacosConfigurationPropertiesBinder
2021-07-15 01:44:06 +08:00
realJackSun b87a4136f0 Release 0.2.8-bugfix, upgrade the nacos-spring-project denpendency to 1.1.1, add synchronized in NacosBootConfigurationPropertiesBinder:doBind 2021-07-15 01:39:42 +08:00
realJackSun 1ffd948f90
Update Nacos-client dependency to 2.0.2 (#203) 2021-07-12 14:42:46 +08:00
realJackSun d363a2b86d
Change the version to 0.2.8 (#198) 2021-06-24 09:28:58 +08:00
JackSun-Developer 1285740ecf
Change the dependency nacos-client to 1.4.2 (#196) 2021-06-04 15:41:25 +08:00
JackSun-Developer d9086a3e1c
Change the version to 0.2.5 (#193) 2021-05-25 19:56:28 +08:00
邪影oO 6b50bc39df
Merge pull request #191 from JackSun-Developer/20210524_1725
[master] upgrade spring-nacos-context version to 1.1.0
2021-05-24 17:30:24 +08:00
JackSun-Developer 437f1e579a [master] upgrade spring-nacos-context version to 1.1.0 2021-05-24 17:17:17 +08:00
mai.jh 93641fbbc5
Add a reset Nacos Log Config listener. (#183)
* for: nacos issue#4567 ,Add a reset Nacos Log Config listener.

* Remove redundant dependency
2021-04-16 10:27:38 +08:00
dependabot[bot] 446278b767
chore(deps): bump log4j (#137)
Bumps log4j from 2.11.2 to 2.13.2.

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-04-15 16:16:39 +08:00
Xiaoshuang Li d77d02926d
fix default value (#173)
Co-authored-by: 李晓双 <lixiaoshuang@172-15-67-144.lightspeed.miamfl.sbcglobal.net>
2021-03-04 11:04:52 +08:00
shalk(xiao kun) 39efc09c56
Update NacosPropertiesBuilder.java (#178)
fix https://github.com/alibaba/nacos/issues/3845
2021-03-04 11:00:33 +08:00
邪影oO 8a89b5f1df
版本号由0.2.7升级到2.0.0 (#166)
* 版本号由0.2.7升级到2.0.0

* readme中增加版本号与spring boot对应关系
2020-12-07 12:43:35 +08:00
赵延 256a35cbd9
upgrade spring-nacos-context version to 1.0.0 (#155) 2020-11-23 10:57:05 +08:00
liaochuntao e9290b86b8
Merge pull request #116 from chuntaojun/feature_remote_first
Feature remote first
2020-03-17 13:39:35 +08:00
chuntaojun 9e20b30214 feat: support remote config Take precedence over local configuration 2020-03-17 13:34:59 +08:00
chuntaojun 6ce80631a7 refactor(config): Adjust the position 2020-03-16 18:15:02 +08:00
chuntaojun 7a762603b7 refactor(config): Remote configuration support has a higher priority than application.proprties 2020-03-16 17:57:03 +08:00
liaochuntao f4a6216bab
Update README.md 2020-03-09 21:07:57 +08:00
liaochuntao f887cf4870
Merge pull request #113 from chuntaojun/feature_auth_master
support nacos auth sys
2020-03-09 21:01:21 +08:00
chuntaojun fb58598ff1 fix: fix test bug 2020-03-09 20:57:41 +08:00
chuntaojun a759ddac7c feat: support nacos auth sys 2020-03-09 20:26:24 +08:00
chuntaojun a993a173ad refactor: update nacos-client version to 1.2.0 2020-03-09 20:17:39 +08:00
liaochuntao 7cb8a79bc4
Merge pull request #104 from ZShUn/master
1.添加username password参数
2020-03-09 18:16:20 +08:00
liaochuntao d48c075941
Merge pull request #111 from mayyamus/fix/log_info
增加toString()方法,解决打印日志时显示对象的内存地址
2020-03-07 22:30:01 +08:00
jh.ma 9d4ad10765 增加toString()方法,解决打印日志时显示对象的内存地址 2020-03-07 20:58:10 +08:00
ZShUn 246d3ba599 1.格式化代码 2020-02-11 14:58:29 +08:00
ZShUn 5ef932023c 1.修复nacos.config.bootstrap.enable=true时执行SecurityProxy.login方法username、password属性值未初始化问题 2020-02-11 14:42:12 +08:00
ZShUn 499785909f 1.移除NacosConfigProperties.Config.serverAddr默认值
2.添加NacosConfigProperties.Config username password属性
2020-02-11 12:44:11 +08:00
ZShUn e3c30a6d30 1.添加username password参数 2020-02-10 23:42:38 +08:00
liaochuntao 213755347a
Merge pull request #101 from ZShUn/master
1.取消NacosDiscoveryAutoDeregister和NacosDiscoveryAutoRegister中applicati…
2020-01-19 13:05:05 +08:00
ZShUn 1d8b73be35 Revert "1.删除eclipse配置文件"
This reverts commit fa0f5bf9
2020-01-19 12:36:37 +08:00
ZShUn fa0f5bf96a 1.删除eclipse配置文件 2020-01-18 23:07:34 +08:00
ZShUn dbd76289cd 1.取消NacosDiscoveryAutoDeregister和NacosDiscoveryAutoRegister中applicationName默认值
2.修复NacosDiscoveryAutoDeregister和NacosDiscoveryAutoRegister日志打印serviceName可能为空情况
3.修复nacos-discovery-example pom文件packaging配置问题
2020-01-18 23:05:54 +08:00
liaochuntao 6663e64f45
Merge pull request #98 from chuntaojun/develop
Add default values for some parameters
2019-12-17 22:41:49 +08:00
chuntaojun 280b82de59 refactor: the code specification adjusts and adds default values 2019-12-14 14:43:01 +08:00
chuntaojun ee232e873c docs: update readme 2019-12-13 14:03:11 +08:00
liaochuntao 101f7cc499
Merge pull request #94 from chuntaojun/master
update nacos-client version to 1.1.4
2019-10-29 18:59:48 +08:00
chuntaojun e0f7df9601 fix(config): fix The method signature error 2019-10-29 18:53:18 +08:00
chuntaojun aa2131ecd2 docs: 2019-10-29 18:33:31 +08:00
chuntaojun f7664c5c85 fix(config): fix issue #81 2019-10-25 14:02:11 +08:00
chuntaojun 5e09a4f3c4 refactor: 2019-10-24 23:14:56 +08:00
chuntaojun a20b99fe00 refactor(config): Optimizing the allocation of binding code 2019-10-23 15:27:19 +08:00
chuntaojun 76ca15d233 fix(config): Repair to remove useless attribute logic 2019-10-21 15:04:11 +08:00
chuntaojun feb84a307e style: Add code format file 2019-10-18 13:54:43 +08:00
chuntaojun 41caa35b53 feat: 2019-10-11 18:02:33 +08:00
chuntaojun f85fa97d03 fix(config): Fix configuration error filtering result in the loss of the problem 2019-09-20 22:24:20 +08:00
chuntaojun 8f071c1ce1 refactor(config): Realize the object attribute value filtering 2019-09-20 22:00:05 +08:00
chuntaojun 8dac3c52b0 fix(config): fix issue #84 2019-09-17 11:04:33 +08:00
liaochuntao 4b40b45847
Merge pull request #83 from chuntaojun/master
refactor(config)
2019-09-15 08:45:23 +08:00
chuntaojun 49fad25bb1 refactor(config): Optimize the code 2019-09-15 08:35:48 +08:00
chuntaojun 77f981e559 fix(config): Repair the load error log level configuration 2019-09-12 14:41:26 +08:00
liaochuntao 1f24267890
Merge pull request #80 from chuntaojun/master
fix(discovery): Repair group parameter error
2019-09-12 12:44:40 +08:00
chuntaojun 4f7c0a4cf1 fix(discovery): Repair group parameter error 2019-09-12 12:34:38 +08:00
liaochuntao 934b88888f
Merge pull request #77 from chuntaojun/master
Code optimization
2019-09-12 10:35:08 +08:00
chuntaojun f4fc82fa91 refactor(all): 2019-09-12 09:31:56 +08:00
chuntaojun dc0b3e99d9 refactor(all): 2019-09-12 09:30:47 +08:00
liaochuntao aeba4c52a1
Merge pull request #70 from leshalv/master
优化nacos maven配置 修复 #71 #72 问题
2019-09-12 09:17:51 +08:00
liaochuntao 22bf8d4503
Merge pull request #76 from chuntaojun/master
refactor(all): update version to 0.2.4
2019-09-12 08:45:50 +08:00
chuntaojun 1383070e8c refactor(all): update version to 0.2.4 2019-09-11 15:39:00 +08:00
liaochuntao 3eb4f70845
Merge pull request #74 from chuntaojun/feat_issue_73
feat(config): feat issue #73
2019-09-10 22:59:17 +08:00
chuntaojun f181d782ee feat(config): feat issue #73 2019-09-10 22:34:16 +08:00
SanLi 1d1e018213 移除developer 2019-09-10 13:59:13 +08:00
SanLi 7b95406a4b 添加additional-spring-configuration-metadata.json,已针对其他元数据处理,例如 nacos.discovery.register 2019-09-10 12:48:06 +08:00
SanLi 992e388352 👥 新增开发者信息 2019-09-10 12:45:22 +08:00
SanLi c6fb1d43aa 删除源码中 spring-configuration-metadata.json 屏蔽 maven-compiler-plugin <compilerArgument>-proc:none</compilerArgument> 属性,使其可以自动生成spring-configuration-metadata.json 2019-09-10 12:41:47 +08:00
SanLi 486b932265 ⬆️ 添加 maven-deploy-plugin 版本声明,修复maven控制台warning提示 2019-09-10 12:30:39 +08:00
SanLi 9796467878 ⬆️ 优化spring-boot-starter 依赖引入方式,去掉<scope>true</scope>,修复maven控制台warning异常 2019-09-10 12:22:54 +08:00
SanLi b86128d20e ⬆️ 升级 parent模块中 maven-compiler-plugin 版本为3.8.0,删除maven-source-plugin.version 声明,添加主项目 pom.xml properties 标签 maven-source-plugin.version 声明,指定版本为3.1.0,并优化maven-source-plugin 插件配置 2019-09-10 12:18:58 +08:00
liaochuntao e0fc1349a4
Merge pull request #67 from chuntaojun/feat_auto_deregister_2.x
Feat auto deregister 2.x
2019-09-10 09:34:26 +08:00
chuntaojun d03abe7a05 refactor(config): 2019-09-10 09:29:48 +08:00
chuntaojun 4f058183c4 refactor: 2019-09-10 00:00:35 +08:00
chuntaojun 4f7dbeabf0 refactor(config): Optimizing the allocation of organization and management 2019-09-09 23:57:59 +08:00
chuntaojun bed5ddf121 fix(config): Repair dataIds pull error and listeners are added 2019-09-09 23:47:40 +08:00
chuntaojun 7da27530c9 fix(config、naming): 2019-09-08 16:10:14 +08:00
chuntaojun d1ac6d7b44 feat(config、naming): Support services for automatic logout function and optimizing the config module 2019-09-08 15:48:53 +08:00
chuntaojun 09cfcbb0f4 refactor(Add more dataId configuration): 2019-09-01 23:08:30 +08:00
liaochuntao 6c42e8ea6b
Merge pull request #51 from chuntaojun/master
feat(config): support ramRoleName paramter
2019-08-16 12:53:46 +08:00
chuntaojun f0d48d31c2 feat(config): support ramRoleName paramter 2019-08-16 12:48:36 +08:00
liaochuntao cff1741940
Merge pull request #50 from chuntaojun/master
update version to 0.2.3
2019-08-16 12:18:09 +08:00
chuntaojun 5329d725b3 refactor: Upgrade depend on nacos-spring-project to 0.3.3 2019-08-16 12:10:24 +08:00
chuntaojun f818a5189d chore: update version to 0.2.3 2019-08-15 15:38:33 +08:00
chuntaojun 367066d03a refactor: merge feat_auto_reigster 2019-08-12 08:46:53 +08:00
chuntaojun 812adfc284 docs(config): Modify the configuration file description information 2019-08-11 21:24:22 +08:00
chuntaojun 4025a41188 fix(config): Fix configuration file loading problem 2019-08-08 19:33:42 +08:00
liaochuntao 85fcedb21d
Merge pull request #44 from chuntaojun/feat_auto_reigster
Feat auto reigster
2019-08-02 20:57:15 +08:00
chuntaojun 0c9b4559a3 test: modif test case 2019-08-02 20:31:38 +08:00
chuntaojun dcc9191b03 fix(config): fix load log setting bug 2019-08-02 18:54:09 +08:00
chuntaojun 0ae9561fd6 feat(naming): support auto register service 2019-08-02 18:45:40 +08:00
liaochuntao 947c94d8ba
Merge pull request #42 from chuntaojun/master
Fix issue #41: support spring profile active
2019-08-02 16:55:21 +08:00
chuntaojun 130f077b5b feat(config): support log config setting 2019-08-02 16:48:16 +08:00
chuntaojun 40a22a8454 fix(config): support spring profile active 2019-08-01 11:58:52 +08:00
liaochuntao a3650ad76a
Merge pull request #39 from chuntaojun/master
refactor(config): update version to 0.2.2
2019-07-25 12:14:03 +08:00
chuntaojun 87e8db83b4 refactor(config): update version to 0.2.2 2019-07-25 11:38:57 +08:00
liaochuntao ee65dc9112
Update README.md 2019-07-19 11:58:59 +08:00
liaochuntao f952f840bd
Merge pull request #34 from chuntaojun/master
fix(config): remove error code
2019-07-19 11:58:16 +08:00
120 changed files with 9049 additions and 1127 deletions

2
.gitignore vendored
View File

@ -29,3 +29,5 @@ hs_err_pid*
.settings .settings
target target
.DS_Store
.flattened-pom.xml

View File

@ -6,12 +6,10 @@ notifications:
on_success: change on_success: change
on_failure: always on_failure: always
dist: trusty
language: java language: java
jdk: jdk:
- openjdk10
- openjdk8 - openjdk8
- openjdk7
script: script:

206
NACOS-AOT-QUICK-START.md Normal file
View File

@ -0,0 +1,206 @@
## Nacos AOT
### prerequisites
- GraalVM22.0+ (JDK17)
- native-image
- Nacos Server
If you haven't downloaded GraalVM, you can download it from [Download GraalVM](https://www.graalvm.org/downloads/).
If you don't have a native-image environment, you can configure according to [Native Image](https://www.graalvm.org/latest/reference-manual/native-image/).
You have to start a Nacos Server in backend , If you don't know steps, you can learn about [quick start](https://nacos.io/en-us/docs/quick-start.html).
### Quick Start
The complete code for this example can be found at: [`nacos-aot-sample`](nacos-spring-boot-samples/nacos-aot-sample)
1. Because SpringBoot2 does not support aot, you must specify SpringBoot as SpringBoot3 in dependency management:
```xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.0.6</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
```
2. You would add [`nacos-config-spring-boot-starter`](nacos-config-spring-boot-starter) or [`nacos-discovery-spring-boot-starter`](nacos-discovery-spring-boot-starter) in your Spring application's dependencies :
```xml
<dependencies>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-config-spring-boot-starter</artifactId>
<version>${latest.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-discovery-spring-boot-starter</artifactId>
<version>${latest.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
```
3. In order to use the process-aot feature of SpringBoot and more conveniently compile native-image programs, we also need `spring-boot-maven-plugin` and `native-maven-plugin`:
```xml
<profiles>
<profile>
<id>native</id>
<build>
<plugins>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>0.9.25</version>
<executions>
<execution>
<id>compile</id>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
<configuration>
<classesDirectory>${project.build.outputDirectory}</classesDirectory>
<mainClass>com.alibaba.boot.nacos.sample.AotApplication</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>process-aot</id>
<goals>
<goal>process-aot</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
```
4. You could define some configurations in `application.properties`:
```properties
nacos.config.server-addr=localhost:8848
nacos.discovery.server-addr=localhost:8848
```
> `nacos.config.server-addr` and `nacos.discovery.server-addr` attribute configure "\${host}:${port}" of your Nacos Server
5. You could using `@SpringBootApplication` to annotate main class like normal SpringBoot Application and startup:
```java
@SpringBootApplication
@NacosPropertySource(dataId = "example", autoRefreshed = true)
public class AotApplication {
public static void main(String[] args) {
SpringApplication.run(AotApplication.class, args);
}
}
```
Note: `@NacosPropertySource` is used to specify the data-id of the configuration.
6. Let's try the functions of `@NacosInjected` and `@NacosValue`, for more usage, see [Nacos Spring Project](https://github.com/nacos-group/nacos-spring-project).
```java
@Controller
public class AotController {
@NacosInjected
private ConfigService configService;
@NacosInjected
private NamingService namingService;
@NacosValue(value = "${flag:false}", autoRefreshed = true)
private boolean flag;
@ResponseBody
@RequestMapping(value = "/config/get", method = GET)
public String getConfig() throws NacosException {
return configService.getConfig("example", "DEFAULT_GROUP", 5000);
}
@ResponseBody
@RequestMapping(value = "/naming/get", method = GET)
public List<Instance> getNaming(@RequestParam("serviceName") String serviceName) throws NacosException {
return namingService.getAllInstances(serviceName);
}
@ResponseBody
@RequestMapping(value = "/flag/get", method = GET)
public boolean getFlag() {
return flag;
}
}
```
7. Publish the configuration to the Nacos Server by calling the Nacos Open API, with dataId of example and content of `flag=true`
```shell
curl -X POST "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=example&group=DEFAULT_GROUP&content=flag=true"
```
8. Enable the tracing agent on the command line with the `java` command from the GraalVM JDK:
```shell
$JAVA_HOME/bin/java -agentlib:native-image-agent=config-output-dir=/path/to/config-dir/ ...
```
Note: For more information about tracing agent, see [Collect Metadata with the Tracing Agent](https://www.graalvm.org/latest/reference-manual/native-image/metadata/AutomaticMetadataCollection/).
9. Run the java program and follow the steps below to use the program:
1. Open `localhost:8080/config/get` with a browser, and the browser responds with `flag=true`.
2. Open `localhost:8080/flag/get` with a browser, and the browser responds with `true`.
3. Publish the configuration to the Nacos Server by calling the Nacos Open API, with dataId of example and content of `flag=false`
```shell
curl -X POST "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=example&group=DEFAULT_GROUP&content=flag=false"
```
4. Open `localhost:8080/flag/get` with a browser, and the browser responds with `false`.
5. Register a service named example with Nacos server by calling Nacos Open API.
```shell
curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=example&ip=127.0.0.1&port=8080'
```
6. Open `localhost:8080/naming/get?serviceName=example` with a browser, and the browser responds with information about the service you just registered.
10. Close the program and copy the file just generated to the `classpath:META-INF/native-image/` folder, The file path is specified in step 8.
Note: [`nacos-aot-sample`](nacos-spring-boot-samples/nacos-aot-sample) already includes these files, but you can still use the files you just generated.
11. Run the following command and you will find the compiled executable program in the `target` folder.
```shell
mvn -DskipTests=true clean package -Pnative
```
12. This executable program is what we want! Run the program and try step 9 again.
## Relative Projects
* [Alibaba Nacos](https://github.com/alibaba/nacos)
* [Alibaba Spring Context Support](https://github.com/alibaba/spring-context-support)
* [Nacos Spring Project](https://github.com/nacos-group/nacos-spring-project)
* [Nacos Spring Cloud Project](https://github.com/spring-cloud-incubator/spring-cloud-alibaba)

144
NACOS-CONFIG-QUICK-START.md Normal file
View File

@ -0,0 +1,144 @@
### Nacos Config
First, you have to start a Nacos Server in backend , If you don't know steps, you can learn about [quick start](https://nacos.io/en-us/docs/quick-start.html).
Suppose your Nacos Server is startup, you would add [`nacos-config-spring-boot-starter`](nacos-config-spring-boot-starter) in your Spring application's dependencies :
```xml
<dependencies>
...
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-config-spring-boot-starter</artifactId>
<version>${latest.version}</version>
</dependency>
...
</dependencies>
```
Note: Version [0.2.x.RELEASE](https://mvnrepository.com/artifact/com.alibaba.boot/nacos-config-spring-boot-starter) is compatible with the Spring Boot 2.x and the Spring Boot 3.x. Version [0.1.x.RELEASE](https://mvnrepository.com/artifact/com.alibaba.boot/nacos-config-spring-boot-starter) is compatible with the Spring Boot 1.x.
After that, you could define some configurations in `application.properties`:
```properties
nacos.config.server-addr=localhost:8848
```
> `nacos.config.server-addr` attribute configures "\${host}:${port}" of your Nacos Server
Then you could using `@SpringBootApplication` to annotate main class like normal SpringBoot Application and startup:
```java
@SpringBootApplication
public class ConfigApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigApplication.class, args);
}
}
```
If you'd like to use "Distributed Configuration" features, `ConfigService` is a core service interface to get or publish config, you could use "Dependency Injection" to inject `ConfigService` instance in your Spring Beans.
```java
@Service
public class ConfigServiceDemo {
@NacosInjected
private ConfigService configService;
public void demoGetConfig() {
try {
String dataId = "{dataId}";
String group = "{group}";
String content = configService.getConfig(dataId, groupId, 5000);
System.out.println(content);
} catch (NacosException e) {
e.printStackTrace();
}
}
...
}
```
above code equals below one:
```java
try {
// Initialize the configuration service, and the console automatically obtains the following parameters through the sample code.
String serverAddr = "{serverAddr}";
String dataId = "{dataId}";
String group = "{group}";
Properties properties = new Properties();
properties.put("serverAddr", serverAddr);
ConfigService configService = NacosFactory.createConfigService(properties);
// Actively get the configuration.
String content = configService.getConfig(dataId, group, 5000);
System.out.println(content);
} catch (NacosException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
```
## Endpoint
Nacos config starter support the implementation of Spring Boot actuator endpoints.
**Prerequisite:**
Adding `nacos-config-spring-boot-actuator` to your pom.xml in Nacos Config Project.
Then Configure your endpoint security strategy.
* Spring Boot1.x
```properties
management.security.enabled=false
```
* Spring Boot2.x or Spring Boot3.x
```properties
management.endpoints.web.exposure.include=*
```
To view the endpoint information, visit the following URLS:
* Spring Boot1.x: URL is http://127.0.0.1:10011/nacos-config.
* Spring Boot2.x or Spring Boot3.x: URL is http://127.0.0.1:10011/actuator/nacos-config.
## Health Checks
`nacos-config-spring-boot-actuator` support the standard Spring Boot `HealthIndicator` as a production-ready feature , which will be aggregated into Spring Boot's `Health` and exported on `HealthEndpoint` that works MVC (Spring Web MVC) if it is available.
Suppose a Spring Boot Web application did not specify `management.server.port`(SpringBoot1.x using `management.port`), you can access http://localhost:{port}/actuator/health (SpringBoot1.x visit http://localhost:{port}/health) via Web Client and will get a response with JSON format is like below :
```json
{
"status": "UP",
"details": {
"nacosConfig": {
"status": "UP"
},
"diskSpace": {
"status": "UP",
"details": {
"total": 250140434432,
"free": 52323512320,
"threshold": 10485760
}
}
}
}
```
For more information about Nacos Spring, see [Nacos Spring Project](https://github.com/nacos-group/nacos-spring-project).
## Relative Projects
* [Alibaba Nacos](https://github.com/alibaba/nacos)
* [Alibaba Spring Context Support](https://github.com/alibaba/spring-context-support)
* [Nacos Spring Project](https://github.com/nacos-group/nacos-spring-project)
* [Nacos Spring Cloud Project](https://github.com/spring-cloud-incubator/spring-cloud-alibaba)

View File

@ -0,0 +1,131 @@
### Nacos Discovery
First, you have to start a Nacos Server in backend , If you don't know steps, you can learn about [quick start](https://nacos.io/en-us/docs/quick-start.html).
Suppose your Nacos Server is startup, you would add [`nacos-discovery-spring-boot-starter`](nacos-discovery-spring-boot-starter) in your Spring application's dependencies :
```xml
<dependencies>
...
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-discovery-spring-boot-starter</artifactId>
<version>${latest.version}</version>
</dependency>
...
</dependencies>
```
Note: Version [0.2.x.RELEASE](https://mvnrepository.com/artifact/com.alibaba.boot/nacos-discovery-spring-boot-starter) is compatible with the Spring Boot 2.x and the Spring Boot 3.x. Version [0.1.x.RELEASE](https://mvnrepository.com/artifact/com.alibaba.boot/nacos-discovery-spring-boot-starter) is compatible with the Spring Boot 1.x.
After that, you could define some configurations in `application.properties`:
```properties
nacos.discovery.server-addr=localhost:8848
```
> `nacos.discovery.server-addr` attribute configures "\${host}:${port}" of your Nacos Server
Then you could using `@SpringBootApplication` to annotate main class like normal SpringBoot Application and startup:
```java
@SpringBootApplication
public class DiscoveryApplication {
public static void main(String[] args) {
SpringApplication.run(DiscoveryApplication.class, args);
}
}
```
If you'd like to use "Service Registry" features, `NamingService` is a core service interface to get or publish config, you could use "Dependency Injection" to inject `NamingService` instance in your Spring Beans.
```java
@Service
public class NamingServiceDemo {
@NacosInjected
private NamingService namingService;
public void demoRegisterService() {
try {
namingService.registerInstance("test-service", "1.1.1.1", 8080);
} catch (NacosException e) {
e.printStackTrace();
}
}
...
}
```
above code equals below one:
```java
try {
// Initialize the naming service, and the console automatically obtains the following parameters through the sample code.
String serverAddr = "{serverAddr}";
Properties properties = new Properties();
properties.put("serverAddr", serverAddr);
NamingService naming = NamingFactory.createNamingService(properties);
namingService.registerInstance("test-service", "1.1.1.1", 8080);
} catch (NacosException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
```
For more information about Nacos Spring, see [Nacos Spring Project](https://github.com/nacos-group/nacos-spring-project).
## Endpoint
Nacos discovery starter also support the implementation of Spring Boot actuator endpoints.
**Prerequisite:**
Adding `nacos-discovery-spring-boot-actuator` to your pom.xml in Nacos Discovery Project.
Then Configure your endpoint security strategy.
* Spring Boot1.x
```properties
management.security.enabled=false
```
* Spring Boot2.x or Spring Boot3.x
```properties
management.endpoints.web.exposure.include=*
```
To view the endpoint information, visit the following URLS:
* Spring Boot1.x: URL is http://127.0.0.1:10012/nacos-discovery.
* Spring Boot2.x or Spring Boot3.x: URL is http://127.0.0.1:10012/actuator/nacos-discovery.
## Health Checks
`nacos-discovery-spring-boot-actuator` support the standard Spring Boot `HealthIndicator` as a production-ready feature , which will be aggregated into Spring Boot's `Health` and exported on `HealthEndpoint` that works MVC (Spring Web MVC) if it is available.
Suppose a Spring Boot Web application did not specify `management.server.port`(SpringBoot1.x using `management.port`), you can access http://localhost:{port}/actuator/health (SpringBoot1.x visit http://localhost:{port}/health) via Web Client and will get a response with JSON format is like below :
```json
{
"status": "UP",
"details": {
"nacosDiscovery": {
"status": "UP"
},
"diskSpace": {
"status": "UP",
"details": {
"total": 250140434432,
"free": 52323680256,
"threshold": 10485760
}
}
}
}
```

252
README.md
View File

@ -18,276 +18,48 @@ Nacos Spring Boot Project consist of two parts: `nacos-config-spring-boot` and `
`nacos-discovery-spring-boot` module is using for Service Discovery, Service Health Check and Dynamic DNS Service. `nacos-discovery-spring-boot` module is using for Service Discovery, Service Health Check and Dynamic DNS Service.
Additionally, Nacos Spring Boot Project already supports native-image.
## Samples ## Samples
- [Nacos Config Sample](https://github.com/nacos-group/nacos-spring-boot-project/tree/master/nacos-spring-boot-samples/nacos-config-sample) - [Nacos Config Sample](https://github.com/nacos-group/nacos-spring-boot-project/tree/master/nacos-spring-boot-samples/nacos-config-sample)
- [Nacos Discovery Sample](https://github.com/nacos-group/nacos-spring-boot-project/tree/master/nacos-spring-boot-samples/nacos-discovery-sample) - [Nacos Discovery Sample](https://github.com/nacos-group/nacos-spring-boot-project/tree/master/nacos-spring-boot-samples/nacos-discovery-sample)
- [Nacos AOT Sample](https://github.com/nacos-group/nacos-spring-boot-project/tree/master/nacos-spring-boot-samples/nacos-aot-sample)
## Dependencies & Compatibility ## Dependencies & Compatibility
**master branch** **Version: 0.2.x / 2.x.x ( branch master )**
| Dependencies | Compatibility | | Dependencies | Compatibility |
| -------------- | ------------- | | -------------- | ------------- |
| Java | 1.8+ | | Java | 1.8+ |
| Spring Boot | 2.0.3.RELEASE | | Spring Boot | 2.0.3.RELEASE |
| Nacos-Spring-Context | 1.1.0 |
**1.x branch** **Version: 0.1.x / 1.x.x ( branch: 1.x )**
| Dependencies | Compatibility | | Dependencies | Compatibility |
| -------------- | ------------- | | -------------- | ------------- |
| Java | 1.7+ | | Java | 1.7+ |
| Spring Boot | 1.4.1.RELEASE | | Spring Boot | 1.4.1.RELEASE |
| Nacos-Spring-Context | 1.1.0 |
## Quick Start ## Quick Start
### Nacos Config
First, you have to start a Nacos Server in backend , If you don't know steps, you can learn about [quick start](https://nacos.io/en-us/docs/quick-start.html). - [Nacos Config Quick Start](https://github.com/nacos-group/nacos-spring-boot-project/blob/master/NACOS-CONFIG-QUICK-START.md)
Suppose your Nacos Server is startup, you would add [`nacos-config-spring-boot-starter`](nacos-config-spring-boot-starter) in your Spring application's dependencies : - [Nacos Discovery Quick Start](https://github.com/nacos-group/nacos-spring-boot-project/blob/master/NACOS-DISCOVERY-QUICK-START.md)
```xml - [Nacos AOT Quick Start](https://github.com/nacos-group/nacos-spring-boot-project/blob/master/NACOS-AOT-QUICK-START.md)
<dependencies>
...
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-config-spring-boot-starter</artifactId>
<version>${latest.version}</version>
</dependency>
...
</dependencies>
```
After that, you could define some configurations in `application.properties`:
```properties
nacos.config.server-addr=localhost
```
> `nacos.config.server-addr` attribute configures "\${host}:${port}" of your Nacos Server
Then you could using `@SpringBootApplication` to annotate main class like normal SpringBoot Application and startup:
```java
@SpringBootApplication
public class ConfigApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigApplication.class, args);
}
}
```
If you'd like to use "Distributed Configuration" features, `ConfigService` is a core service interface to get or publish config, you could use "Dependency Injection" to inject `ConfigService` instance in your Spring Beans.
```java
@Service
public class ConfigServiceDemo {
@NacosInjected
private ConfigService configService;
public void demoGetConfig() {
try {
String dataId = "{dataId}";
String group = "{group}";
String content = configService.getConfig(dataId, groupId, 5000);
System.out.println(content);
} catch (NacosException e) {
e.printStackTrace();
}
}
...
}
```
above code equals below one:
```java
try {
// Initialize the configuration service, and the console automatically obtains the following parameters through the sample code.
String serverAddr = "{serverAddr}";
String dataId = "{dataId}";
String group = "{group}";
Properties properties = new Properties();
properties.put("serverAddr", serverAddr);
ConfigService configService = NacosFactory.createConfigService(properties);
// Actively get the configuration.
String content = configService.getConfig(dataId, group, 5000);
System.out.println(content);
} catch (NacosException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
```
### Nacos Discovery
First, you have to start a Nacos Server in backend , If you don't know steps, you can learn about [quick start](https://nacos.io/en-us/docs/quick-start.html).
Suppose your Nacos Server is startup, you would add [`nacos-discovery-spring-boot-starter`](nacos-discovery-spring-boot-starter) in your Spring application's dependencies :
```xml
<dependencies>
...
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-discovery-spring-boot-starter</artifactId>
<version>${latest.version}</version>
</dependency>
...
</dependencies>
```
After that, you could define some configurations in `application.properties`:
```properties
nacos.discovery.server-addr=localhost
```
> `nacos.discovery.server-addr` attribute configures "\${host}:${port}" of your Nacos Server
Then you could using `@SpringBootApplication` to annotate main class like normal SpringBoot Application and startup:
```java
@SpringBootApplication
public class DiscoveryApplication {
public static void main(String[] args) {
SpringApplication.run(DiscoveryApplication.class, args);
}
}
```
If you'd like to use "Service Registry" features, `NamingService` is a core service interface to get or publish config, you could use "Dependency Injection" to inject `NamingService` instance in your Spring Beans.
```java
@Service
public class NamingServiceDemo {
@NacosInjected
private NamingService namingService;
public void demoRegisterService() {
try {
namingService.registerInstance("test-service", "1.1.1.1", 8080);
} catch (NacosException e) {
e.printStackTrace();
}
}
...
}
```
above code equals below one:
```java
try {
// Initialize the naming service, and the console automatically obtains the following parameters through the sample code.
String serverAddr = "{serverAddr}";
Properties properties = new Properties();
properties.put("serverAddr", serverAddr);
NamingService naming = NamingFactory.createNamingService(properties);
namingService.registerInstance("test-service", "1.1.1.1", 8080);
} catch (NacosException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
```
For more information about Nacos Spring, see [Nacos Spring Project](https://github.com/nacos-group/nacos-spring-project).
## Endpoint
Nacos config starter and Nacos discovery starter also support the implementation of Spring Boot actuator endpoints.
**Prerequisite:**
Adding `nacos-config-spring-boot-actuator` to your pom.xml in Nacos Config Project.
Adding `nacos-discovery-spring-boot-actuator` to your pom.xml in Nacos Discovery Project.
Then Configure your endpoint security strategy.
* Spring Boot1.x
```properties
management.security.enabled=false
```
* Spring Boot2.x
```properties
management.endpoints.web.exposure.include=*
```
To view the endpoint information, visit the following URLS:
Nacos Config Project :
* Spring Boot1.x: Nacos Config Endpoint URL is http://127.0.0.1:10011/nacos-config.
* Spring Boot2.x: Nacos Config Endpoint URL is http://127.0.0.1:10011/actuator/nacos-config.
Nacos Discovery Project:
* Spring Boot1.x: Nacos Discovery Endpoint URL is http://127.0.0.1:10012/nacos-discovery.
* Spring Boot2.x: Nacos Discovery Endpoint URL is http://127.0.0.1:10012/actuator/nacos-discovery.
## Health Checks
`nacos-config-spring-boot-actuator` and `nacos-discovery-spring-boot-actuator` support the standard Spring Boot `HealthIndicator` as a production-ready feature , which will be aggregated into Spring Boot's `Health` and exported on `HealthEndpoint` that works MVC (Spring Web MVC) if it is available.
Suppose a Spring Boot Web application did not specify `management.server.port`(SpringBoot1.x using `management.port`), you can access http://localhost:{port}/actuator/health (SpringBoot1.x visit http://localhost:{port}/health) via Web Client and will get a response with JSON format is like below :
Nacos Config Project:
```json
{
"status": "UP",
"details": {
"nacosConfig": {
"status": "UP"
},
"diskSpace": {
"status": "UP",
"details": {
"total": 250140434432,
"free": 52323512320,
"threshold": 10485760
}
}
}
}
```
Nacos Discovery Project:
```json
{
"status": "UP",
"details": {
"nacosDiscovery": {
"status": "UP"
},
"diskSpace": {
"status": "UP",
"details": {
"total": 250140434432,
"free": 52323680256,
"threshold": 10485760
}
}
}
}
```
For more information about Nacos Spring, see [Nacos Spring Project](https://github.com/nacos-group/nacos-spring-project). For more information about Nacos Spring, see [Nacos Spring Project](https://github.com/nacos-group/nacos-spring-project).
For more information about user guide, see [User Guide](https://github.com/nacos-group/nacos-spring-boot-project/wiki/%E7%94%A8%E6%88%B7%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3).
## Relative Projects ## Relative Projects
* [Alibaba Nacos](https://github.com/alibaba/nacos) * [Alibaba Nacos](https://github.com/alibaba/nacos)

View File

@ -18,7 +18,7 @@
<parent> <parent>
<artifactId>nacos-spring-boot-parent</artifactId> <artifactId>nacos-spring-boot-parent</artifactId>
<groupId>com.alibaba.boot</groupId> <groupId>com.alibaba.boot</groupId>
<version>0.1.4</version> <version>${revision}</version>
<relativePath>../nacos-spring-boot-parent/pom.xml</relativePath> <relativePath>../nacos-spring-boot-parent/pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -81,6 +81,18 @@
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId> <artifactId>nacos-spring-context</artifactId>
<optional>true</optional> <optional>true</optional>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${nacos.version}</version>
</dependency> </dependency>
<!-- Test Dependencies --> <!-- Test Dependencies -->

View File

@ -17,11 +17,8 @@
package com.alibaba.boot.nacos.actuate.autoconfigure; package com.alibaba.boot.nacos.actuate.autoconfigure;
import com.alibaba.boot.nacos.actuate.endpoint.NacosConfigEndpoint; import com.alibaba.boot.nacos.actuate.endpoint.NacosConfigEndpoint;
import com.alibaba.boot.nacos.config.NacosConfigConstants; import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.condition.ConditionalOnEnabledEndpoint;
import org.springframework.boot.actuate.endpoint.Endpoint;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -33,12 +30,11 @@ import org.springframework.context.annotation.Configuration;
* @see Endpoint * @see Endpoint
*/ */
@Configuration @Configuration
@ConditionalOnClass(Endpoint.class)
public class NacosConfigEndpointAutoConfiguration { public class NacosConfigEndpointAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
@ConditionalOnEnabledEndpoint(NacosConfigConstants.ENDPOINT_PREFIX) @ConditionalOnAvailableEndpoint
public NacosConfigEndpoint nacosEndpoint() { public NacosConfigEndpoint nacosEndpoint() {
return new NacosConfigEndpoint(); return new NacosConfigEndpoint();
} }

View File

@ -20,8 +20,8 @@ import com.alibaba.boot.nacos.actuate.health.NacosConfigHealthIndicator;
import com.alibaba.boot.nacos.config.NacosConfigConstants; import com.alibaba.boot.nacos.config.NacosConfigConstants;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration; import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.ConditionalOnEnabledHealthIndicator; import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.AutoConfigureBefore;

View File

@ -23,18 +23,20 @@ import java.util.Properties;
import com.alibaba.boot.nacos.common.PropertiesUtils; import com.alibaba.boot.nacos.common.PropertiesUtils;
import com.alibaba.boot.nacos.config.NacosConfigConstants; import com.alibaba.boot.nacos.config.NacosConfigConstants;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.config.annotation.NacosConfigListener; import com.alibaba.nacos.api.config.annotation.NacosConfigListener;
import com.alibaba.nacos.api.config.annotation.NacosConfigurationProperties; import com.alibaba.nacos.api.config.annotation.NacosConfigurationProperties;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.spring.context.event.config.NacosConfigMetadataEvent; import com.alibaba.nacos.spring.context.event.config.NacosConfigMetadataEvent;
import com.alibaba.nacos.spring.util.NacosUtils; import com.alibaba.nacos.spring.util.NacosUtils;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.commons.lang3.ClassUtils; import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.endpoint.AbstractEndpoint; import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener; import org.springframework.context.ApplicationListener;
import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.ConfigurableEnvironment;
@ -48,19 +50,16 @@ import static com.alibaba.nacos.spring.util.NacosBeanUtils.CONFIG_GLOBAL_NACOS_P
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a> * @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
* @see Endpoint * @see Endpoint
*/ */
public class NacosConfigEndpoint extends AbstractEndpoint<Map<String, Object>> @Endpoint(id = NacosConfigConstants.ENDPOINT_PREFIX)
public class NacosConfigEndpoint
implements ApplicationListener<NacosConfigMetadataEvent> { implements ApplicationListener<NacosConfigMetadataEvent> {
@Autowired @Autowired
private ApplicationContext applicationContext; private ApplicationContext applicationContext;
private Map<String, JSONObject> nacosConfigMetadataMap = new HashMap<>(); private Map<String, JsonNode> nacosConfigMetadataMap = new HashMap<>(8);
public NacosConfigEndpoint() { @ReadOperation
super(NacosConfigConstants.ENDPOINT_PREFIX);
}
@Override
public Map<String, Object> invoke() { public Map<String, Object> invoke() {
Map<String, Object> result = new HashMap<>(8); Map<String, Object> result = new HashMap<>(8);
@ -85,37 +84,37 @@ public class NacosConfigEndpoint extends AbstractEndpoint<Map<String, Object>>
public void onApplicationEvent(NacosConfigMetadataEvent event) { public void onApplicationEvent(NacosConfigMetadataEvent event) {
String key = buildMetadataKey(event); String key = buildMetadataKey(event);
if (StringUtils.isNotEmpty(key) && !nacosConfigMetadataMap.containsKey(key)) { if (StringUtils.isNotEmpty(key) && !nacosConfigMetadataMap.containsKey(key)) {
JSONObject jsonObject = new JSONObject(); ObjectNode jsonNode = JacksonUtils.createEmptyJsonNode();
jsonObject.put("groupId", event.getGroupId()); jsonNode.put("groupId", event.getGroupId());
jsonObject.put("dataId", event.getDataId()); jsonNode.put("dataId", event.getDataId());
if (ClassUtils.isAssignable(event.getSource().getClass(), if (ClassUtils.isAssignable(event.getSource().getClass(),
AnnotationMetadata.class)) { AnnotationMetadata.class)) {
jsonObject.put("origin", "NacosPropertySource"); jsonNode.put("origin", "NacosPropertySource");
jsonObject.put("target", jsonNode.put("target",
((AnnotationMetadata) event.getSource()).getClassName()); ((AnnotationMetadata) event.getSource()).getClassName());
} }
else if (ClassUtils.isAssignable(event.getSource().getClass(), else if (ClassUtils.isAssignable(event.getSource().getClass(),
NacosConfigListener.class)) { NacosConfigListener.class)) {
jsonObject.put("origin", "NacosConfigListener"); jsonNode.put("origin", "NacosConfigListener");
Method configListenerMethod = (Method) event.getAnnotatedElement(); Method configListenerMethod = (Method) event.getAnnotatedElement();
jsonObject.put("target", jsonNode.put("target",
configListenerMethod.getDeclaringClass().getName() + ":" configListenerMethod.getDeclaringClass().getName() + ":"
+ configListenerMethod.toString()); + configListenerMethod.toString());
} }
else if (ClassUtils.isAssignable(event.getSource().getClass(), else if (ClassUtils.isAssignable(event.getSource().getClass(),
NacosConfigurationProperties.class)) { NacosConfigurationProperties.class)) {
jsonObject.put("origin", "NacosConfigurationProperties"); jsonNode.put("origin", "NacosConfigurationProperties");
jsonObject.put("target", event.getBeanType().getName()); jsonNode.put("target", event.getBeanType().getName());
} }
else if (ClassUtils.isAssignable(event.getSource().getClass(), else if (ClassUtils.isAssignable(event.getSource().getClass(),
Element.class)) { Element.class)) {
jsonObject.put("origin", "NacosPropertySource"); jsonNode.put("origin", "NacosPropertySource");
jsonObject.put("target", event.getXmlResource().toString()); jsonNode.put("target", event.getXmlResource().toString());
} }
else { else {
throw new RuntimeException("unknown NacosConfigMetadataEvent"); throw new RuntimeException("unknown NacosConfigMetadataEvent");
} }
nacosConfigMetadataMap.put(key, jsonObject); nacosConfigMetadataMap.put(key, jsonNode);
} }
} }

View File

@ -19,8 +19,8 @@ package com.alibaba.boot.nacos.actuate.health;
import java.util.Properties; import java.util.Properties;
import com.alibaba.boot.nacos.common.PropertiesUtils; import com.alibaba.boot.nacos.common.PropertiesUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.config.ConfigService; import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.spring.factory.CacheableEventPublishingNacosServiceFactory; import com.alibaba.nacos.spring.factory.CacheableEventPublishingNacosServiceFactory;
import com.alibaba.nacos.spring.factory.NacosServiceFactory; import com.alibaba.nacos.spring.factory.NacosServiceFactory;
import com.alibaba.nacos.spring.metadata.NacosServiceMetaData; import com.alibaba.nacos.spring.metadata.NacosServiceMetaData;
@ -38,6 +38,7 @@ import org.springframework.context.ApplicationContext;
* @see HealthIndicator * @see HealthIndicator
*/ */
public class NacosConfigHealthIndicator extends AbstractHealthIndicator { public class NacosConfigHealthIndicator extends AbstractHealthIndicator {
@Autowired @Autowired
private ApplicationContext applicationContext; private ApplicationContext applicationContext;
@ -53,7 +54,7 @@ public class NacosConfigHealthIndicator extends AbstractHealthIndicator {
NacosServiceMetaData nacosServiceMetaData = (NacosServiceMetaData) configService; NacosServiceMetaData nacosServiceMetaData = (NacosServiceMetaData) configService;
Properties properties = nacosServiceMetaData.getProperties(); Properties properties = nacosServiceMetaData.getProperties();
builder.withDetail( builder.withDetail(
JSON.toJSONString( JacksonUtils.toJson(
PropertiesUtils.extractSafeProperties(properties)), PropertiesUtils.extractSafeProperties(properties)),
configService.getServerStatus()); configService.getServerStatus());
} }

View File

@ -0,0 +1,56 @@
[
{
"name": "org.springframework.core.env.ConfigurableEnvironment",
"allDeclaredMethods": true,
"allDeclaredFields": true,
"allDeclaredConstructors": true,
"allPublicMethods": true,
"allPublicFields": true,
"allPublicConstructors": true
},
{
"name": "java.util.Properties",
"allDeclaredMethods": true,
"allDeclaredFields": true,
"allDeclaredConstructors": true,
"allPublicMethods": true,
"allPublicFields": true,
"allPublicConstructors": true
},
{
"name": "org.springframework.core.type.AnnotationMetadata",
"allDeclaredMethods": true,
"allDeclaredFields": true,
"allDeclaredConstructors": true,
"allPublicMethods": true,
"allPublicFields": true,
"allPublicConstructors": true
},
{
"name": "com.alibaba.nacos.api.config.annotation.NacosConfigListener",
"allDeclaredMethods": true,
"allDeclaredFields": true,
"allDeclaredConstructors": true,
"allPublicMethods": true,
"allPublicFields": true,
"allPublicConstructors": true
},
{
"name": "com.alibaba.nacos.api.config.annotation.NacosConfigurationProperties",
"allDeclaredMethods": true,
"allDeclaredFields": true,
"allDeclaredConstructors": true,
"allPublicMethods": true,
"allPublicFields": true,
"allPublicConstructors": true
},
{
"name": "org.w3c.dom.Element",
"allDeclaredMethods": true,
"allDeclaredFields": true,
"allDeclaredConstructors": true,
"allPublicMethods": true,
"allPublicFields": true,
"allPublicConstructors": true
}
]

View File

@ -0,0 +1,2 @@
com.alibaba.boot.nacos.actuate.autoconfigure.NacosConfigEndpointAutoConfiguration
com.alibaba.boot.nacos.actuate.autoconfigure.NacosConfigHealthIndicatorAutoConfiguration

View File

@ -0,0 +1,51 @@
/*
*
* * Licensed to the Apache Software Foundation (ASF) under one or more
* * contributor license agreements. See the NOTICE file distributed with
* * this work for additional information regarding copyright ownership.
* * The ASF licenses this file to You under the Apache License, Version 2.0
* * (the "License"); you may not use this file except in compliance with
* * the License. You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*/
package com.alibaba.boot.nacos.actuate.autoconfigure;
import com.alibaba.boot.nacos.actuate.endpoint.NacosConfigEndpoint;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* {@link NacosConfigEndpointAutoConfiguration} Test
* @ClassName: NacosConfigEndpointAutoConfigurationTest
* @Author: SuperZ1999
* @Date: 2023/9/28
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {NacosConfigEndpointAutoConfiguration.class})
@TestPropertySource(properties = {
"management.endpoints.web.exposure.include=nacos-config"
})
public class NacosConfigEndpointAutoConfigurationTest {
@Autowired
private ApplicationContext context;
@Test
public void testNacosConfigEndpointBean() {
Assert.assertNotNull(context.getBean(NacosConfigEndpoint.class));
}
}

View File

@ -0,0 +1,47 @@
/*
*
* * Licensed to the Apache Software Foundation (ASF) under one or more
* * contributor license agreements. See the NOTICE file distributed with
* * this work for additional information regarding copyright ownership.
* * The ASF licenses this file to You under the Apache License, Version 2.0
* * (the "License"); you may not use this file except in compliance with
* * the License. You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*/
package com.alibaba.boot.nacos.actuate.autoconfigure;
import com.alibaba.boot.nacos.actuate.health.NacosConfigHealthIndicator;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* {@link NacosConfigHealthIndicatorAutoConfiguration} Test
* @ClassName: NacosConfigHealthIndicatorAutoConfigurationTest
* @Author: SuperZ1999
* @Date: 2023/9/28
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {NacosConfigHealthIndicatorAutoConfiguration.class})
public class NacosConfigHealthIndicatorAutoConfigurationTest {
@Autowired
private ApplicationContext context;
@Test
public void testNacosConfigHealthIndicatorBean() {
Assert.assertNotNull(context.getBean(NacosConfigHealthIndicator.class));
}
}

View File

@ -18,7 +18,7 @@
<parent> <parent>
<groupId>com.alibaba.boot</groupId> <groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-parent</artifactId> <artifactId>nacos-spring-boot-parent</artifactId>
<version>0.1.4</version> <version>${revision}</version>
<relativePath>../nacos-spring-boot-parent</relativePath> <relativePath>../nacos-spring-boot-parent</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -27,6 +27,18 @@
<packaging>jar</packaging> <packaging>jar</packaging>
<name>Nacos Config Spring Boot AutoConfigure</name> <name>Nacos Config Spring Boot AutoConfigure</name>
<description>Nacos Config Spring Boot AutoConfigure</description> <description>Nacos Config Spring Boot AutoConfigure</description>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies> <dependencies>
@ -54,14 +66,33 @@
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId> <artifactId>nacos-spring-context</artifactId>
<optional>true</optional> <optional>true</optional>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${nacos.version}</version>
</dependency>
<dependency> <dependency>
<groupId>com.alibaba.boot</groupId> <groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-base</artifactId> <artifactId>nacos-spring-boot-base</artifactId>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-aot</artifactId>
<optional>true</optional>
</dependency>
<!-- Test Dependencies --> <!-- Test Dependencies -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>

View File

@ -25,7 +25,7 @@ import com.alibaba.nacos.spring.context.annotation.config.EnableNacosConfig;
*/ */
public interface NacosConfigConstants { public interface NacosConfigConstants {
String ENDPOINT_PREFIX = "nacos_config"; String ENDPOINT_PREFIX = "nacos-config";
String ENABLED = EnableNacosConfig.CONFIG_PREFIX + "enabled"; String ENABLED = EnableNacosConfig.CONFIG_PREFIX + "enabled";

View File

@ -18,7 +18,7 @@ package com.alibaba.boot.nacos.config.autoconfigure;
/** /**
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a> * @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since 0.1.3 * @since 0.2.3
*/ */
public class NacosBootConfigException extends RuntimeException { public class NacosBootConfigException extends RuntimeException {

View File

@ -17,83 +17,88 @@
package com.alibaba.boot.nacos.config.autoconfigure; package com.alibaba.boot.nacos.config.autoconfigure;
import java.util.Properties; import java.util.Properties;
import java.util.function.Function;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties; import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.boot.nacos.config.util.Function; import com.alibaba.boot.nacos.config.util.NacosConfigLoader;
import com.alibaba.boot.nacos.config.util.NacosConfigLoaderFactory;
import com.alibaba.boot.nacos.config.util.NacosConfigPropertiesUtils; import com.alibaba.boot.nacos.config.util.NacosConfigPropertiesUtils;
import com.alibaba.boot.nacos.config.util.NacosConfigUtils;
import com.alibaba.nacos.api.config.ConfigService; import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.utils.SnapShotSwitch;
import com.alibaba.nacos.spring.factory.CacheableEventPublishingNacosServiceFactory; import com.alibaba.nacos.spring.factory.CacheableEventPublishingNacosServiceFactory;
import com.alibaba.nacos.spring.util.NacosBeanUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.ConfigurableEnvironment;
/** /**
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a> * @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since 0.1.2 * @since 0.2.2
*/ */
public class NacosConfigApplicationInitializer public class NacosConfigApplicationContextInitializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> { implements ApplicationContextInitializer<ConfigurableApplicationContext> {
private final Logger logger = LoggerFactory private final Logger logger = LoggerFactory
.getLogger(NacosConfigApplicationInitializer.class); .getLogger(NacosConfigApplicationContextInitializer.class);
private ConfigurableEnvironment environment;
private final NacosConfigEnvironmentProcessor processor; private final NacosConfigEnvironmentProcessor processor;
private final CacheableEventPublishingNacosServiceFactory singleton = CacheableEventPublishingNacosServiceFactory
.getSingleton();
private final Function<Properties, ConfigService> builder = properties -> {
try {
return singleton.createConfigService(properties);
}
catch (NacosException e) {
throw new NacosBootConfigException(
"ConfigService can't be created with properties : " + properties, e);
}
};
private ConfigurableEnvironment environment;
private NacosConfigProperties nacosConfigProperties; private NacosConfigProperties nacosConfigProperties;
public NacosConfigApplicationInitializer( public NacosConfigApplicationContextInitializer(
NacosConfigEnvironmentProcessor configEnvironmentProcessor) { NacosConfigEnvironmentProcessor configEnvironmentProcessor) {
this.processor = configEnvironmentProcessor; this.processor = configEnvironmentProcessor;
} }
@Override @Override
public void initialize(ConfigurableApplicationContext context) { public void initialize(ConfigurableApplicationContext context) {
final CacheableEventPublishingNacosServiceFactory singleton = CacheableEventPublishingNacosServiceFactory
.getSingleton();
singleton.setApplicationContext(context); singleton.setApplicationContext(context);
environment = context.getEnvironment(); environment = context.getEnvironment();
nacosConfigProperties = NacosConfigPropertiesUtils nacosConfigProperties = NacosConfigPropertiesUtils
.buildNacosConfigProperties(environment); .buildNacosConfigProperties(environment);
processor.publishDeferService(context); final NacosConfigLoader configLoader = NacosConfigLoaderFactory.getSingleton(builder);
if (!processor.snapshotEnable()){
SnapShotSwitch.setIsSnapShot(false);
}
if (!enable()) { if (!enable()) {
logger.info("[Nacos Config Boot] : The preload configuration is not enabled"); logger.info("[Nacos Config Boot] : The preload configuration is not enabled");
} }
else { else {
final Function<Properties, ConfigService> builder = new Function<Properties, ConfigService>() {
@Override // If it opens the log level loading directly will cache
public ConfigService apply(Properties input) { // DeferNacosPropertySource release
try {
return singleton.createConfigService(input);
}
catch (NacosException e) {
throw new NacosBootConfigException(
"ConfigService can't be created with properties : "
+ input,
e);
}
}
};
final NacosConfigUtils configUtils = new NacosConfigUtils(
nacosConfigProperties, environment, builder);
if (processor.enable()) { if (processor.enable()) {
configUtils processor.publishDeferService(context);
configLoader
.addListenerIfAutoRefreshed(processor.getDeferPropertySources()); .addListenerIfAutoRefreshed(processor.getDeferPropertySources());
} }
else { else {
configUtils.loadConfig(); configLoader.loadConfig(environment, nacosConfigProperties);
configUtils.addListenerIfAutoRefreshed(); configLoader.addListenerIfAutoRefreshed();
} }
} }
} }
private boolean enable() { private boolean enable() {
return nacosConfigProperties.getBootstrap().isEnable(); return processor.enable() || nacosConfigProperties.getBootstrap().isEnable();
} }
} }

View File

@ -16,6 +16,7 @@
*/ */
package com.alibaba.boot.nacos.config.autoconfigure; package com.alibaba.boot.nacos.config.autoconfigure;
import com.alibaba.boot.nacos.aot.context.EnableNacosConfigAotProcessor;
import com.alibaba.boot.nacos.config.NacosConfigConstants; import com.alibaba.boot.nacos.config.NacosConfigConstants;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties; import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.nacos.spring.context.annotation.config.EnableNacosConfig; import com.alibaba.nacos.spring.context.annotation.config.EnableNacosConfig;
@ -36,10 +37,10 @@ import static com.alibaba.nacos.spring.util.NacosBeanUtils.CONFIG_GLOBAL_NACOS_P
*/ */
@ConditionalOnProperty(name = NacosConfigConstants.ENABLED, matchIfMissing = true) @ConditionalOnProperty(name = NacosConfigConstants.ENABLED, matchIfMissing = true)
@ConditionalOnMissingBean(name = CONFIG_GLOBAL_NACOS_PROPERTIES_BEAN_NAME) @ConditionalOnMissingBean(name = CONFIG_GLOBAL_NACOS_PROPERTIES_BEAN_NAME)
@EnableNacosConfig
@EnableConfigurationProperties(value = NacosConfigProperties.class) @EnableConfigurationProperties(value = NacosConfigProperties.class)
@ConditionalOnClass(name = "org.springframework.boot.bind.RelaxedDataBinder") @ConditionalOnClass(name = "org.springframework.boot.context.properties.bind.Binder")
@Import(value = { NacosConfigBootBeanDefinitionRegistrar.class }) @Import(value = { NacosConfigBootBeanDefinitionRegistrar.class, EnableNacosConfigAotProcessor.class })
@EnableNacosConfig
public class NacosConfigAutoConfiguration { public class NacosConfigAutoConfiguration {
} }

View File

@ -30,7 +30,7 @@ import org.springframework.core.type.AnnotationMetadata;
/** /**
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a> * @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since 0.1.2 * @since 0.2.2
*/ */
@Configuration @Configuration
public class NacosConfigBootBeanDefinitionRegistrar public class NacosConfigBootBeanDefinitionRegistrar

View File

@ -20,19 +20,21 @@ import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.function.Function;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties; import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.boot.nacos.config.util.Function; import com.alibaba.boot.nacos.config.util.NacosConfigLoader;
import com.alibaba.boot.nacos.config.util.NacosConfigLoaderFactory;
import com.alibaba.boot.nacos.config.util.NacosConfigPropertiesUtils; import com.alibaba.boot.nacos.config.util.NacosConfigPropertiesUtils;
import com.alibaba.boot.nacos.config.util.NacosConfigUtils; import com.alibaba.boot.nacos.config.util.log.LogAutoFreshProcess;
import com.alibaba.nacos.api.NacosFactory; import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.config.ConfigService; import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.spring.factory.CacheableEventPublishingNacosServiceFactory; import com.alibaba.nacos.spring.factory.CacheableEventPublishingNacosServiceFactory;
import com.alibaba.nacos.spring.util.NacosUtils; import com.alibaba.nacos.spring.util.NacosUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor; import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
@ -40,62 +42,61 @@ import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.ConfigurableEnvironment;
/** /**
* In the Context to create premise before loading the log configuration information
*
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a> * @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since 0.1.3 * @since 0.2.3
*/ */
public class NacosConfigEnvironmentProcessor public class NacosConfigEnvironmentProcessor
implements EnvironmentPostProcessor, Ordered { implements EnvironmentPostProcessor, Ordered {
private final Logger logger = LoggerFactory private final Logger logger = LoggerFactory
.getLogger(NacosConfigEnvironmentProcessor.class); .getLogger(NacosConfigEnvironmentProcessor.class);
private final CacheableEventPublishingNacosServiceFactory nacosServiceFactory = CacheableEventPublishingNacosServiceFactory private final CacheableEventPublishingNacosServiceFactory nacosServiceFactory = CacheableEventPublishingNacosServiceFactory
.getSingleton(); .getSingleton();
private final LinkedList<NacosConfigUtils.DeferNacosPropertySource> deferPropertySources = new LinkedList<>();
private final Map<String, ConfigService> serviceCache = new HashMap<>(8); private final Map<String, ConfigService> serviceCache = new HashMap<>(8);
private final LinkedList<NacosConfigLoader.DeferNacosPropertySource> deferPropertySources = new LinkedList<>();
private NacosConfigProperties nacosConfigProperties; private NacosConfigProperties nacosConfigProperties;
private final Function<Properties, ConfigService> builder = new Function<Properties, ConfigService>() { // Because ApplicationContext has not been injected at preload time, need to manually
// cache the created Service to prevent duplicate creation
@Override private final Function<Properties, ConfigService> builder = properties -> {
public ConfigService apply(Properties input) {
try { try {
final String key = NacosUtils.identify(input); final String key = NacosUtils.identify(properties);
ConfigService service = serviceCache.get(key); if (serviceCache.containsKey(key)) {
if (service != null) {
return serviceCache.get(key); return serviceCache.get(key);
} }
service = NacosFactory.createConfigService(input); final ConfigService configService = NacosFactory
serviceCache.put(key, service); .createConfigService(properties);
return nacosServiceFactory.deferCreateService(service, input); serviceCache.put(key, configService);
return nacosServiceFactory.deferCreateService(configService, properties);
} }
catch (NacosException e) { catch (NacosException e) {
throw new NacosBootConfigException( throw new NacosBootConfigException(
"ConfigService can't be created with properties : " + input, e); "ConfigService can't be created with properties : " + properties, e);
}
} }
}; };
@Override @Override
public void postProcessEnvironment(ConfigurableEnvironment environment, public void postProcessEnvironment(ConfigurableEnvironment environment,
SpringApplication application) { SpringApplication application) {
application.addInitializers(new NacosConfigApplicationInitializer(this)); application.addInitializers(new NacosConfigApplicationContextInitializer(this));
nacosConfigProperties = NacosConfigPropertiesUtils nacosConfigProperties = NacosConfigPropertiesUtils
.buildNacosConfigProperties(environment); .buildNacosConfigProperties(environment);
if (enable()) { if (enable()) {
System.out.println( System.out.println(
"[Nacos Config Boot] : The preload log configuration is enabled"); "[Nacos Config Boot] : The preload log configuration is enabled");
loadConfig(environment); NacosConfigLoader nacosConfigLoader = NacosConfigLoaderFactory.getSingleton(builder);
loadConfig(nacosConfigLoader, environment, nacosConfigProperties);
LogAutoFreshProcess.build(environment, nacosConfigProperties, nacosConfigLoader, builder).process();
} }
} }
private void loadConfig(ConfigurableEnvironment environment) { private void loadConfig(NacosConfigLoader configLoader, ConfigurableEnvironment environment, NacosConfigProperties nacosConfigProperties) {
final NacosConfigUtils configUtils = new NacosConfigUtils(nacosConfigProperties, configLoader.loadConfig(environment, nacosConfigProperties);
environment, builder); // set defer NacosPropertySource
configUtils.loadConfig(); deferPropertySources.addAll(configLoader.getNacosPropertySources());
// set defer nacosPropertySource
deferPropertySources.addAll(configUtils.getNacosPropertySources());
} }
boolean enable() { boolean enable() {
@ -103,22 +104,29 @@ public class NacosConfigEnvironmentProcessor
&& nacosConfigProperties.getBootstrap().isLogEnable(); && nacosConfigProperties.getBootstrap().isLogEnable();
} }
LinkedList<NacosConfigUtils.DeferNacosPropertySource> getDeferPropertySources() { boolean snapshotEnable() {
return nacosConfigProperties != null
&& nacosConfigProperties.getBootstrap().isSnapshotEnable();
}
LinkedList<NacosConfigLoader.DeferNacosPropertySource> getDeferPropertySources() {
return deferPropertySources; return deferPropertySources;
} }
// Do not set the minimum priority for future expansion needs
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE - 5;
}
void publishDeferService(ApplicationContext context) { void publishDeferService(ApplicationContext context) {
try { try {
nacosServiceFactory.publishDeferService(context); nacosServiceFactory.publishDeferService(context);
serviceCache.clear(); serviceCache.clear();
} }
catch (Exception e) { catch (Exception e) {
logger.error("publish defer ConfigService has some error : {}", e); logger.error("publish defer ConfigService has some error", e);
} }
} }
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
} }

View File

@ -16,46 +16,74 @@
*/ */
package com.alibaba.boot.nacos.config.binder; package com.alibaba.boot.nacos.config.binder;
import java.util.Properties; import java.lang.reflect.Method;
import com.alibaba.boot.nacos.config.util.BinderUtils;
import com.alibaba.nacos.api.config.ConfigService; import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.annotation.NacosConfigurationProperties; import com.alibaba.nacos.api.config.annotation.NacosConfigurationProperties;
import com.alibaba.nacos.spring.context.properties.config.NacosConfigurationPropertiesBinder; import com.alibaba.nacos.spring.context.properties.config.NacosConfigurationPropertiesBinder;
import org.slf4j.Logger; import com.alibaba.nacos.spring.core.env.NacosPropertySource;
import org.slf4j.LoggerFactory; import com.alibaba.nacos.spring.util.ObjectUtils;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.ResolvableType;
import static com.alibaba.nacos.spring.util.NacosUtils.toProperties; import org.springframework.core.env.StandardEnvironment;
/** /**
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a> * @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since 0.1.2 * @since 0.2.2
*/ */
public class NacosBootConfigurationPropertiesBinder public class NacosBootConfigurationPropertiesBinder
extends NacosConfigurationPropertiesBinder { extends NacosConfigurationPropertiesBinder {
private final Logger logger = LoggerFactory private final ConfigurableApplicationContext applicationContext;
.getLogger(NacosBootConfigurationPropertiesBinder.class);
private ConfigurableApplicationContext context; private final StandardEnvironment environment = new StandardEnvironment();
public NacosBootConfigurationPropertiesBinder( public NacosBootConfigurationPropertiesBinder(
ConfigurableApplicationContext applicationContext) { ConfigurableApplicationContext applicationContext) {
super(applicationContext); super(applicationContext);
this.context = applicationContext; this.applicationContext = applicationContext;
} }
@Override @Override
protected void doBind(Object bean, String beanName, String dataId, String groupId, protected void doBind(Object bean, String beanName, String dataId, String groupId,
String configType, NacosConfigurationProperties properties, String content, String configType, NacosConfigurationProperties properties, String content,
ConfigService configService) { ConfigService configService) {
Properties prop = toProperties(dataId, groupId, content, configType); synchronized (this) {
BinderUtils.bind(bean, properties.prefix(), prop); String name = "nacos-bootstrap-" + beanName;
publishBoundEvent(bean, beanName, dataId, groupId, properties, content, NacosPropertySource propertySource = new NacosPropertySource(dataId, groupId, name, content, configType);
configService); environment.getPropertySources().addLast(propertySource);
ObjectUtils.cleanMapOrCollectionField(bean);
Binder binder = Binder.get(environment);
ResolvableType type = getBeanType(bean, beanName);
Bindable<?> target = Bindable.of(type).withExistingValue(bean);
binder.bind(properties.prefix(), target);
publishBoundEvent(bean, beanName, dataId, groupId, properties, content, configService);
publishMetadataEvent(bean, beanName, dataId, groupId, properties); publishMetadataEvent(bean, beanName, dataId, groupId, properties);
environment.getPropertySources().remove(name);
}
} }
private ResolvableType getBeanType(Object bean, String beanName) {
Method factoryMethod = findFactoryMethod(beanName);
if (factoryMethod != null) {
return ResolvableType.forMethodReturnType(factoryMethod);
}
return ResolvableType.forClass(bean.getClass());
}
public Method findFactoryMethod(String beanName) {
ConfigurableListableBeanFactory beanFactory = this.applicationContext.getBeanFactory();
if (beanFactory.containsBeanDefinition(beanName)) {
BeanDefinition beanDefinition = beanFactory.getMergedBeanDefinition(beanName);
if (beanDefinition instanceof RootBeanDefinition) {
return ((RootBeanDefinition) beanDefinition).getResolvedFactoryMethod();
}
}
return null;
}
} }

View File

@ -0,0 +1,67 @@
/*
* Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.boot.nacos.config.logging;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.boot.nacos.config.util.NacosConfigPropertiesUtils;
import com.alibaba.nacos.client.logging.NacosLogging;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.GenericApplicationListener;
import org.springframework.core.Ordered;
import org.springframework.core.ResolvableType;
/**
* Reload nacos log configuration file, after
* {@link org.springframework.boot.context.logging.LoggingApplicationListener}.
*
* @author mai.jh
*/
public class NacosLoggingListener implements GenericApplicationListener {
@Override
public boolean supportsEventType(ResolvableType resolvableType) {
Class<?> type = resolvableType.getRawClass();
if (type != null) {
return ApplicationEnvironmentPreparedEvent.class.isAssignableFrom(type);
}
return false;
}
@Override
public boolean supportsSourceType(Class<?> aClass) {
return true;
}
@Override
public void onApplicationEvent(ApplicationEvent applicationEvent) {
//If the managed log is enabled, load your own log configuration after loading the user log configuration
ApplicationEnvironmentPreparedEvent applicationEnvironmentPreparedEvent = (ApplicationEnvironmentPreparedEvent) applicationEvent;
NacosConfigProperties nacosConfigProperties = NacosConfigPropertiesUtils.buildNacosConfigProperties(
applicationEnvironmentPreparedEvent.getEnvironment());
if(nacosConfigProperties.getBootstrap().isLogEnable()){
NacosLogging.getInstance().loadConfiguration();
}
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE + 21;
}
}

View File

@ -18,12 +18,13 @@ package com.alibaba.boot.nacos.config.properties;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import com.alibaba.boot.nacos.config.NacosConfigConstants; import com.alibaba.boot.nacos.config.NacosConfigConstants;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.nacos.api.common.Constants; import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.config.ConfigType; import com.alibaba.nacos.api.config.ConfigType;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty; import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -60,7 +61,7 @@ public class NacosConfigProperties {
private String group = Constants.DEFAULT_GROUP; private String group = Constants.DEFAULT_GROUP;
private ConfigType type; private ConfigType type = ConfigType.PROPERTIES;
private String maxRetry; private String maxRetry;
@ -70,12 +71,34 @@ public class NacosConfigProperties {
private boolean enableRemoteSyncConfig = false; private boolean enableRemoteSyncConfig = false;
@JSONField(serialize = false) private String username;
private String password;
private boolean remoteFirst = false;
@JsonIgnore
private List<Config> extConfig = new ArrayList<>(); private List<Config> extConfig = new ArrayList<>();
@NestedConfigurationProperty @NestedConfigurationProperty
private Bootstrap bootstrap = new Bootstrap(); private Bootstrap bootstrap = new Bootstrap();
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getServerAddr() { public String getServerAddr() {
return serverAddr; return serverAddr;
} }
@ -213,6 +236,14 @@ public class NacosConfigProperties {
this.enableRemoteSyncConfig = enableRemoteSyncConfig; this.enableRemoteSyncConfig = enableRemoteSyncConfig;
} }
public boolean isRemoteFirst() {
return remoteFirst;
}
public void setRemoteFirst(boolean remoteFirst) {
this.remoteFirst = remoteFirst;
}
public List<Config> getExtConfig() { public List<Config> getExtConfig() {
return extConfig; return extConfig;
} }
@ -229,11 +260,39 @@ public class NacosConfigProperties {
this.bootstrap = bootstrap; this.bootstrap = bootstrap;
} }
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("NacosConfigProperties{");
sb.append("serverAddr='").append(serverAddr).append('\'');
sb.append(", contextPath='").append(contextPath).append('\'');
sb.append(", encode='").append(encode).append('\'');
sb.append(", endpoint='").append(endpoint).append('\'');
sb.append(", namespace='").append(namespace).append('\'');
sb.append(", accessKey='").append(Objects.isNull(accessKey) ? null : "******").append('\'');
sb.append(", secretKey='").append(Objects.isNull(secretKey) ? null : "******").append('\'');
sb.append(", ramRoleName='").append(ramRoleName).append('\'');
sb.append(", autoRefresh=").append(autoRefresh);
sb.append(", dataId='").append(dataId).append('\'');
sb.append(", dataIds='").append(dataIds).append('\'');
sb.append(", group='").append(group).append('\'');
sb.append(", type=").append(type);
sb.append(", maxRetry='").append(maxRetry).append('\'');
sb.append(", configLongPollTimeout='").append(configLongPollTimeout).append('\'');
sb.append(", configRetryTime='").append(configRetryTime).append('\'');
sb.append(", enableRemoteSyncConfig=").append(enableRemoteSyncConfig);
sb.append(", extConfig=").append(extConfig);
sb.append(", bootstrap=").append(bootstrap);
sb.append('}');
return sb.toString();
}
public static class Bootstrap { public static class Bootstrap {
private boolean enable = false; private boolean enable;
private boolean logEnable = false; private boolean logEnable;
private boolean snapshotEnable;
public boolean isEnable() { public boolean isEnable() {
return enable; return enable;
@ -250,11 +309,29 @@ public class NacosConfigProperties {
public void setLogEnable(boolean logEnable) { public void setLogEnable(boolean logEnable) {
this.logEnable = logEnable; this.logEnable = logEnable;
} }
public boolean isSnapshotEnable() {
return snapshotEnable;
}
public void setSnapshotEnable(boolean snapshotEnable) {
this.snapshotEnable = snapshotEnable;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("Bootstrap{");
sb.append("enable=").append(enable);
sb.append(", snapshotEnable=").append(snapshotEnable);
sb.append(", logEnable=").append(logEnable);
sb.append('}');
return sb.toString();
}
} }
public static class Config { public static class Config {
private String serverAddr = "127.0.0.1:8848"; private String serverAddr;
private String endpoint; private String endpoint;
@ -284,6 +361,26 @@ public class NacosConfigProperties {
private boolean enableRemoteSyncConfig = false; private boolean enableRemoteSyncConfig = false;
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getServerAddr() { public String getServerAddr() {
return serverAddr; return serverAddr;
} }
@ -403,5 +500,28 @@ public class NacosConfigProperties {
public void setEnableRemoteSyncConfig(boolean enableRemoteSyncConfig) { public void setEnableRemoteSyncConfig(boolean enableRemoteSyncConfig) {
this.enableRemoteSyncConfig = enableRemoteSyncConfig; this.enableRemoteSyncConfig = enableRemoteSyncConfig;
} }
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("Config{");
sb.append("serverAddr='").append(serverAddr).append('\'');
sb.append(", endpoint='").append(endpoint).append('\'');
sb.append(", namespace='").append(namespace).append('\'');
sb.append(", accessKey='").append(Objects.isNull(accessKey) ? null : "******").append('\'');
sb.append(", secretKey='").append(Objects.isNull(secretKey) ? null : "******").append('\'');
sb.append(", ramRoleName='").append(ramRoleName).append('\'');
sb.append(", dataId='").append(dataId).append('\'');
sb.append(", dataIds='").append(dataIds).append('\'');
sb.append(", group='").append(group).append('\'');
sb.append(", type=").append(type);
sb.append(", maxRetry='").append(maxRetry).append('\'');
sb.append(", configLongPollTimeout='").append(configLongPollTimeout)
.append('\'');
sb.append(", configRetryTime='").append(configRetryTime).append('\'');
sb.append(", autoRefresh=").append(autoRefresh);
sb.append(", enableRemoteSyncConfig=").append(enableRemoteSyncConfig);
sb.append('}');
return sb.toString();
}
} }
} }

View File

@ -0,0 +1,95 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.boot.nacos.config.support;
import com.alibaba.nacos.spring.core.env.AbstractNacosPropertySourceBuilder;
import com.alibaba.nacos.spring.core.env.NacosPropertySource;
import com.alibaba.nacos.spring.util.parse.DefaultYamlConfigParse;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
/**
* yaml multi profiles.
* <p>
* read nacos propertysource:
* <p>
* 1. {@link AbstractNacosPropertySourceBuilder#doBuild(String, BeanDefinition, Map)}<br/>
* 2. {@link NacosPropertySource#NacosPropertySource(String, String, String, String, String)}<br/>
* 3. {@link com.alibaba.nacos.spring.util.NacosUtils#toProperties(String, String, String, String)}<br/>
* 4. {@link com.alibaba.nacos.spring.util.ConfigParseUtils#toProperties(String, String, String, String)}<br/>
*
* @author <a href="mailto:yanglu_u@126.com">dbses</a>
*/
public class MultiProfilesYamlConfigParseSupport extends DefaultYamlConfigParse implements EnvironmentPostProcessor {
private static final String SPRING_PROFILES = "spring.profiles";
private static String[] profileArray = {};
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
String[] profiles = environment.getActiveProfiles();
// fall back to default profiles
if (profiles.length == 0) {
profiles = environment.getDefaultProfiles();
}
// set once
if (profileArray.length == 0) {
profileArray = profiles;
}
}
@Override
public Map<String, Object> parse(String configText) {
final AtomicReference<Map<String, Object>> result = new AtomicReference<>();
process(map -> {
// first block
if (result.get() == null) {
result.set(map);
} else {
setFromOtherBlock(result, map);
}
}, createYaml(), configText);
return result.get();
}
private void setFromOtherBlock(AtomicReference<Map<String, Object>> result, Map<String, Object> map) {
if (map.get(SPRING_PROFILES) == null) {
result.get().putAll(map);
return;
}
for (String profile : profileArray) {
if (profile.equals(map.get(SPRING_PROFILES))) {
result.get().putAll(map);
}
}
}
/**
* for unit test
*/
static void setProfileArray(String[] profiles) {
profileArray = profiles;
}
}

View File

@ -31,9 +31,9 @@ import org.springframework.core.env.PropertySource;
/** /**
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a> * @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since 0.1.3 * @since 0.2.3
*/ */
public class AttributeExtractTask implements Callable<Map<String, Object>> { public class AttributeExtractTask implements Callable<Map<String, String>> {
private final String prefix; private final String prefix;
private final ConfigurableEnvironment environment; private final ConfigurableEnvironment environment;
@ -44,33 +44,33 @@ public class AttributeExtractTask implements Callable<Map<String, Object>> {
} }
@Override @Override
public Map<String, Object> call() throws Exception { public Map<String, String> call() throws Exception {
List<Map<String, Object>> defer = new LinkedList<>(); List<Map<String, String>> defer = new LinkedList<>();
MutablePropertySources mutablePropertySources = environment.getPropertySources(); MutablePropertySources mutablePropertySources = environment.getPropertySources();
for (PropertySource propertySource : mutablePropertySources) { for (PropertySource propertySource : mutablePropertySources) {
calculate(propertySource.getSource(), defer); calculate(propertySource.getSource(), defer);
} }
Map<String, Object> result = new HashMap<>(32); Map<String, String> result = new HashMap<>(32);
Collections.reverse(defer); Collections.reverse(defer);
for (Map<String, Object> item : defer) { for (Map<String, String> item : defer) {
result.putAll(item); result.putAll(item);
} }
return result; return result;
} }
private void calculate(Object source, List<Map<String, Object>> defer) { private void calculate(Object source, List<Map<String, String>> defer) {
if (source instanceof PropertySource) { if (source instanceof PropertySource) {
calculate(((PropertySource) source).getSource(), defer); calculate(((PropertySource) source).getSource(), defer);
} }
if (source instanceof Map) { if (source instanceof Map) {
Map<String, Object> map = new HashMap<>(8); Map<String, String> map = new HashMap<>(8);
for (Object entry : ((Map) source).entrySet()) { for (Object entry : ((Map) source).entrySet()) {
Map.Entry<Object, Object> element = (Map.Entry<Object, Object>) entry; Map.Entry<Object, Object> element = (Map.Entry<Object, Object>) entry;
String key = String.valueOf(element.getKey()); String key = String.valueOf(element.getKey());
if (key.startsWith(prefix)) { if (key.startsWith(prefix)) {
map.put(key, element.getValue()); map.put(key, String.valueOf(element.getValue()));
} }
} }
if (!map.isEmpty()) { if (!map.isEmpty()) {

View File

@ -20,7 +20,10 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.ListIterator;
import java.util.Properties; import java.util.Properties;
import java.util.function.Function;
import java.util.stream.Collectors;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties; import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.nacos.api.config.ConfigService; import com.alibaba.nacos.api.config.ConfigService;
@ -28,53 +31,57 @@ import com.alibaba.nacos.api.config.ConfigType;
import com.alibaba.nacos.spring.core.env.NacosPropertySource; import com.alibaba.nacos.spring.core.env.NacosPropertySource;
import com.alibaba.nacos.spring.core.env.NacosPropertySourcePostProcessor; import com.alibaba.nacos.spring.core.env.NacosPropertySourcePostProcessor;
import com.alibaba.nacos.spring.util.NacosUtils; import com.alibaba.nacos.spring.util.NacosUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources; import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.util.StringUtils;
import static com.alibaba.nacos.spring.util.NacosUtils.buildDefaultPropertySourceName; import static com.alibaba.nacos.spring.util.NacosUtils.buildDefaultPropertySourceName;
/** /**
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a> * @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since 0.1.3 * @author <a href="mailto:guofuyinan@gmail.com">guofuyinan</a>
* @since 0.2.3
*/ */
public class NacosConfigUtils { public class NacosConfigLoader {
private final Logger logger = LoggerFactory.getLogger(NacosConfigUtils.class); private final Logger logger = LoggerFactory.getLogger(NacosConfigLoader.class);
private final NacosConfigProperties nacosConfigProperties; private Properties globalProperties = new Properties();
private final ConfigurableEnvironment environment;
private Function<Properties, ConfigService> builder;
private List<DeferNacosPropertySource> nacosPropertySources = new LinkedList<>();
public NacosConfigUtils(NacosConfigProperties nacosConfigProperties, private final Function<Properties, ConfigService> builder;
ConfigurableEnvironment environment, private final List<DeferNacosPropertySource> nacosPropertySources = new LinkedList<>();
Function<Properties, ConfigService> builder) {
this.nacosConfigProperties = nacosConfigProperties; public NacosConfigLoader(Function<Properties, ConfigService> builder) {
this.environment = environment;
this.builder = builder; this.builder = builder;
} }
public void loadConfig() { public void loadConfig(ConfigurableEnvironment environment, NacosConfigProperties nacosConfigProperties) {
Properties globalProperties = buildGlobalNacosProperties(); globalProperties = buildGlobalNacosProperties(environment, nacosConfigProperties);
MutablePropertySources mutablePropertySources = environment.getPropertySources(); MutablePropertySources mutablePropertySources = environment.getPropertySources();
List<NacosPropertySource> sources = reqGlobalNacosConfig(globalProperties, List<NacosPropertySource> sources = reqGlobalNacosConfig(environment, globalProperties, nacosConfigProperties);
nacosConfigProperties.getType());
for (NacosConfigProperties.Config config : nacosConfigProperties.getExtConfig()) { for (NacosConfigProperties.Config config : nacosConfigProperties.getExtConfig()) {
List<NacosPropertySource> elements = reqSubNacosConfig(config, List<NacosPropertySource> elements = reqSubNacosConfig(environment, config,
globalProperties, config.getType()); globalProperties, config.getType());
sources.addAll(sources.size(), elements); sources.addAll(elements);
} }
if (nacosConfigProperties.isRemoteFirst()) {
for (ListIterator<NacosPropertySource> itr = sources.listIterator(sources.size()); itr.hasPrevious();) {
mutablePropertySources.addAfter(
StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, itr.previous());
}
} else {
for (NacosPropertySource propertySource : sources) { for (NacosPropertySource propertySource : sources) {
mutablePropertySources.addLast(propertySource); mutablePropertySources.addLast(propertySource);
} }
} }
}
private Properties buildGlobalNacosProperties() { public Properties buildGlobalNacosProperties(ConfigurableEnvironment environment, NacosConfigProperties nacosConfigProperties) {
return NacosPropertiesBuilder.buildNacosProperties( return NacosPropertiesBuilder.buildNacosProperties(environment,
nacosConfigProperties.getServerAddr(), nacosConfigProperties.getServerAddr(),
nacosConfigProperties.getNamespace(), nacosConfigProperties.getEndpoint(), nacosConfigProperties.getNamespace(), nacosConfigProperties.getEndpoint(),
nacosConfigProperties.getSecretKey(), nacosConfigProperties.getSecretKey(),
@ -83,36 +90,35 @@ public class NacosConfigUtils {
nacosConfigProperties.getConfigLongPollTimeout(), nacosConfigProperties.getConfigLongPollTimeout(),
nacosConfigProperties.getConfigRetryTime(), nacosConfigProperties.getConfigRetryTime(),
nacosConfigProperties.getMaxRetry(), nacosConfigProperties.getMaxRetry(),
nacosConfigProperties.isEnableRemoteSyncConfig()); nacosConfigProperties.getContextPath(),
nacosConfigProperties.isEnableRemoteSyncConfig(),
nacosConfigProperties.getUsername(), nacosConfigProperties.getPassword());
} }
private Properties buildSubNacosProperties(Properties globalProperties, private Properties buildSubNacosProperties(ConfigurableEnvironment environment, Properties globalProperties,
NacosConfigProperties.Config config) { NacosConfigProperties.Config config) {
return getProperties(globalProperties, config); Properties sub = NacosPropertiesBuilder.buildNacosProperties(environment,
}
private static Properties getProperties(Properties globalProperties,
NacosConfigProperties.Config config) {
if (StringUtils.isEmpty(config.getServerAddr())) {
return globalProperties;
}
Properties sub = NacosPropertiesBuilder.buildNacosProperties(
config.getServerAddr(), config.getNamespace(), config.getEndpoint(), config.getServerAddr(), config.getNamespace(), config.getEndpoint(),
config.getSecretKey(), config.getAccessKey(), config.getRamRoleName(), config.getSecretKey(), config.getAccessKey(), config.getRamRoleName(),
config.getConfigLongPollTimeout(), config.getConfigRetryTime(), config.getConfigLongPollTimeout(), config.getConfigRetryTime(),
config.getMaxRetry(), config.isEnableRemoteSyncConfig()); config.getMaxRetry(),null, config.isEnableRemoteSyncConfig(),
config.getUsername(), config.getPassword());
NacosPropertiesBuilder.merge(sub, globalProperties); NacosPropertiesBuilder.merge(sub, globalProperties);
return sub; return sub;
} }
private List<NacosPropertySource> reqGlobalNacosConfig(Properties globalProperties, private List<NacosPropertySource> reqGlobalNacosConfig(ConfigurableEnvironment environment, Properties globalProperties,
ConfigType type) { NacosConfigProperties nacosConfigProperties) {
List<String> dataIds = new ArrayList<>(); List<String> dataIds = new ArrayList<>();
// Loads all data-id information into the list in the list // Loads all data-id information into the list in the list
if (StringUtils.isEmpty(nacosConfigProperties.getDataId())) { if (!StringUtils.hasLength(nacosConfigProperties.getDataId())) {
final String ids = environment final String ids = environment
.resolvePlaceholders(nacosConfigProperties.getDataIds()); .resolvePlaceholders(nacosConfigProperties.getDataIds());
dataIds.addAll(Arrays.asList(ids.split(","))); if(StringUtils.hasText(ids)){
dataIds.addAll(Arrays.stream(ids.split(","))
.filter(StringUtils::hasText)
.collect(Collectors.toList()));
}
} }
else { else {
dataIds.add(nacosConfigProperties.getDataId()); dataIds.add(nacosConfigProperties.getDataId());
@ -120,18 +126,18 @@ public class NacosConfigUtils {
final String groupName = environment final String groupName = environment
.resolvePlaceholders(nacosConfigProperties.getGroup()); .resolvePlaceholders(nacosConfigProperties.getGroup());
final boolean isAutoRefresh = nacosConfigProperties.isAutoRefresh(); final boolean isAutoRefresh = nacosConfigProperties.isAutoRefresh();
return new ArrayList<>(Arrays.asList(reqNacosConfig(globalProperties, return new ArrayList<>(Arrays.asList(reqNacosConfig(environment, globalProperties,
dataIds.toArray(new String[0]), groupName, type, isAutoRefresh))); dataIds.toArray(new String[0]), groupName, nacosConfigProperties.getType(), isAutoRefresh)));
} }
private List<NacosPropertySource> reqSubNacosConfig( private List<NacosPropertySource> reqSubNacosConfig(ConfigurableEnvironment environment,
NacosConfigProperties.Config config, Properties globalProperties, NacosConfigProperties.Config config, Properties globalProperties,
ConfigType type) { ConfigType type) {
Properties subConfigProperties = buildSubNacosProperties(globalProperties, Properties subConfigProperties = buildSubNacosProperties(environment, globalProperties,
config); config);
ArrayList<String> dataIds = new ArrayList<>(); ArrayList<String> dataIds = new ArrayList<>();
if (StringUtils.isEmpty(config.getDataId())) { if (!StringUtils.hasLength(config.getDataId())) {
final String ids = environment.resolvePlaceholders(config.getDataId()); final String ids = environment.resolvePlaceholders(config.getDataIds());
dataIds.addAll(Arrays.asList(ids.split(","))); dataIds.addAll(Arrays.asList(ids.split(",")));
} }
else { else {
@ -139,17 +145,18 @@ public class NacosConfigUtils {
} }
final String groupName = environment.resolvePlaceholders(config.getGroup()); final String groupName = environment.resolvePlaceholders(config.getGroup());
final boolean isAutoRefresh = config.isAutoRefresh(); final boolean isAutoRefresh = config.isAutoRefresh();
return new ArrayList<>(Arrays.asList(reqNacosConfig(subConfigProperties, return new ArrayList<>(Arrays.asList(reqNacosConfig(environment, subConfigProperties,
dataIds.toArray(new String[0]), groupName, type, isAutoRefresh))); dataIds.toArray(new String[0]), groupName, type, isAutoRefresh)));
} }
private NacosPropertySource[] reqNacosConfig(Properties configProperties, private NacosPropertySource[] reqNacosConfig(ConfigurableEnvironment environment, Properties configProperties,
String[] dataIds, String groupId, ConfigType type, boolean isAutoRefresh) { String[] dataIds, String groupId, ConfigType type, boolean isAutoRefresh) {
final NacosPropertySource[] propertySources = new NacosPropertySource[dataIds.length]; final NacosPropertySource[] propertySources = new NacosPropertySource[dataIds.length];
for (int i = 0; i < dataIds.length; i++) { for (int i = 0; i < dataIds.length; i++) {
if (StringUtils.isEmpty(dataIds[i])) { if (!StringUtils.hasLength(dataIds[i])) {
continue; continue;
} }
// Remove excess Spaces
final String dataId = environment.resolvePlaceholders(dataIds[i].trim()); final String dataId = environment.resolvePlaceholders(dataIds[i].trim());
final String config = NacosUtils.getContent(builder.apply(configProperties), final String config = NacosUtils.getContent(builder.apply(configProperties),
dataId, groupId); dataId, groupId);
@ -161,9 +168,8 @@ public class NacosConfigUtils {
nacosPropertySource.setType(type.getType()); nacosPropertySource.setType(type.getType());
nacosPropertySource.setGroupId(groupId); nacosPropertySource.setGroupId(groupId);
nacosPropertySource.setAutoRefreshed(isAutoRefresh); nacosPropertySource.setAutoRefreshed(isAutoRefresh);
logger.info( logger.info("load config from nacos, data-id is : {}, group is : {}",
"load config from nacos, data-id is : [{}], group is : [{}], config-text is : [{}]", nacosPropertySource.getDataId(), nacosPropertySource.getGroupId());
dataId, groupId, config);
propertySources[i] = nacosPropertySource; propertySources[i] = nacosPropertySource;
DeferNacosPropertySource defer = new DeferNacosPropertySource( DeferNacosPropertySource defer = new DeferNacosPropertySource(
nacosPropertySource, configProperties, environment); nacosPropertySource, configProperties, environment);
@ -190,6 +196,11 @@ public class NacosConfigUtils {
return nacosPropertySources; return nacosPropertySources;
} }
public Properties getGlobalProperties() {
return globalProperties;
}
// Delay Nacos configuration data source object, used for log level of loading time, // Delay Nacos configuration data source object, used for log level of loading time,
// the cache configuration, wait for after the completion of the Spring Context // the cache configuration, wait for after the completion of the Spring Context
// created in the release // created in the release

View File

@ -0,0 +1,44 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.boot.nacos.config.util;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.nacos.api.config.ConfigService;
import org.springframework.core.env.ConfigurableEnvironment;
import java.util.Properties;
import java.util.function.Function;
/**
* NacosConfigLoaderFactory.
* @author hujun
*/
public class NacosConfigLoaderFactory {
private static volatile NacosConfigLoader nacosConfigLoader;
public static NacosConfigLoader getSingleton(Function<Properties, ConfigService> builder) {
if (nacosConfigLoader == null) {
synchronized (NacosConfigLoaderFactory.class) {
if (nacosConfigLoader == null) {
nacosConfigLoader = new NacosConfigLoader(builder);
}
}
}
return nacosConfigLoader;
}
}

View File

@ -16,55 +16,40 @@
*/ */
package com.alibaba.boot.nacos.config.util; package com.alibaba.boot.nacos.config.util;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import com.alibaba.boot.nacos.config.NacosConfigConstants; import com.alibaba.boot.nacos.config.NacosConfigConstants;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties; import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.nacos.api.config.ConfigService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.core.ResolvableType;
import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.ConfigurableEnvironment;
import java.util.Properties;
import java.util.function.Function;
/** /**
* Springboot used to own property binding configured binding
*
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a> * @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since 0.1.3 * @since 0.2.3
*/ */
public class NacosConfigPropertiesUtils { public class NacosConfigPropertiesUtils {
private static final String PROPERTIES_PREFIX = "nacos";
private static final Logger logger = LoggerFactory private static final Logger logger = LoggerFactory
.getLogger(NacosConfigPropertiesUtils.class); .getLogger(NacosConfigPropertiesUtils.class);
private static Set<String> OBJ_FIELD_NAME = new HashSet<>();
static {
Field[] fields = NacosConfigProperties.class.getDeclaredFields();
for (Field field : fields) {
OBJ_FIELD_NAME.add(field.getName());
}
}
public static NacosConfigProperties buildNacosConfigProperties( public static NacosConfigProperties buildNacosConfigProperties(
ConfigurableEnvironment environment) { ConfigurableEnvironment environment) {
NacosConfigProperties bean = new NacosConfigProperties(); NacosConfigProperties nacosConfigProperties = new NacosConfigProperties();
Binder binder = Binder.get(environment);
AttributeExtractTask task = new AttributeExtractTask(PROPERTIES_PREFIX, ResolvableType type = ResolvableType.forClass(NacosConfigProperties.class);
environment); Bindable<?> target = Bindable.of(type).withExistingValue(nacosConfigProperties);
binder.bind(NacosConfigConstants.PREFIX, target);
try { logger.info("nacosConfigProperties : {}", nacosConfigProperties);
Properties properties = new Properties(); return nacosConfigProperties;
properties.putAll(task.call());
BinderUtils.bind(bean, NacosConfigConstants.PREFIX, properties);
}
catch (Exception e) {
throw new RuntimeException(e);
}
logger.info("nacosConfigProperties : {}", bean);
return bean;
} }
} }

View File

@ -22,53 +22,45 @@ import java.util.Properties;
import com.alibaba.nacos.api.PropertyKeyConst; import com.alibaba.nacos.api.PropertyKeyConst;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.core.env.Environment;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
/** /**
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a> * @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since 0.1.3 * @since 0.2.3
*/ */
public class NacosPropertiesBuilder { public class NacosPropertiesBuilder {
public static Properties buildNacosProperties(String serverAddr, String namespaceId, public static Properties buildNacosProperties(Environment environment,
String endpoint, String secretKey, String accessKey, String ramRoleName, String serverAddr, String namespaceId, String endpoint, String secretKey,
String configLongPollTimeout, String configRetryTimeout, String maxRetry, String accessKey, String ramRoleName, String configLongPollTimeout,
boolean enableRemoteSyncConfig) { String configRetryTimeout, String maxRetry,String contextPath, boolean enableRemoteSyncConfig,
String username, String password) {
Properties properties = new Properties(); Properties properties = new Properties();
if (StringUtils.isNotEmpty(serverAddr)) { processPropertiesData(properties,environment,serverAddr,PropertyKeyConst.SERVER_ADDR);
properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr); processPropertiesData(properties,environment,namespaceId,PropertyKeyConst.NAMESPACE);
} processPropertiesData(properties,environment,endpoint,PropertyKeyConst.ENDPOINT);
if (StringUtils.isNotEmpty(namespaceId)) { processPropertiesData(properties,environment,secretKey,PropertyKeyConst.SECRET_KEY);
properties.put(PropertyKeyConst.NAMESPACE, namespaceId); processPropertiesData(properties,environment,accessKey,PropertyKeyConst.ACCESS_KEY);
} processPropertiesData(properties,environment,ramRoleName,PropertyKeyConst.RAM_ROLE_NAME);
if (StringUtils.isNotEmpty(endpoint)) { processPropertiesData(properties,environment,configLongPollTimeout,PropertyKeyConst.CONFIG_LONG_POLL_TIMEOUT);
properties.put(PropertyKeyConst.ENDPOINT, endpoint); processPropertiesData(properties,environment,configRetryTimeout,PropertyKeyConst.CONFIG_RETRY_TIME);
} processPropertiesData(properties,environment,contextPath,PropertyKeyConst.CONTEXT_PATH);
if (StringUtils.isNotEmpty(secretKey)) { processPropertiesData(properties,environment,maxRetry,PropertyKeyConst.MAX_RETRY);
properties.put(PropertyKeyConst.SECRET_KEY, secretKey); processPropertiesData(properties,environment,username,PropertyKeyConst.USERNAME);
} processPropertiesData(properties,environment,password,PropertyKeyConst.PASSWORD);
if (StringUtils.isNotEmpty(accessKey)) {
properties.put(PropertyKeyConst.ACCESS_KEY, accessKey);
}
if (StringUtils.isNoneEmpty(ramRoleName)) {
properties.put(PropertyKeyConst.RAM_ROLE_NAME, ramRoleName);
}
if (StringUtils.isNotEmpty(configLongPollTimeout)) {
properties.put(PropertyKeyConst.CONFIG_LONG_POLL_TIMEOUT,
configLongPollTimeout);
}
if (StringUtils.isNotEmpty(configRetryTimeout)) {
properties.put(PropertyKeyConst.CONFIG_RETRY_TIME, configRetryTimeout);
}
if (StringUtils.isNotEmpty(maxRetry)) {
properties.put(PropertyKeyConst.MAX_RETRY, maxRetry);
}
properties.put(PropertyKeyConst.ENABLE_REMOTE_SYNC_CONFIG, properties.put(PropertyKeyConst.ENABLE_REMOTE_SYNC_CONFIG,
String.valueOf(enableRemoteSyncConfig)); String.valueOf(enableRemoteSyncConfig));
return properties; return properties;
} }
private static void processPropertiesData(Properties properties,Environment environment,String keyword,String key) {
if (StringUtils.isNotBlank(keyword)) {
properties.put(key ,environment.resolvePlaceholders(keyword));
}
}
public static void merge(Properties targetProperties, Properties sourceProperties) { public static void merge(Properties targetProperties, Properties sourceProperties) {
if (CollectionUtils.isEmpty(sourceProperties)) { if (CollectionUtils.isEmpty(sourceProperties)) {

View File

@ -1,72 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.boot.nacos.config.util.editor;
import java.beans.PropertyEditorSupport;
/**
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since 0.1.3
*/
public class NacosBooleanEditor extends PropertyEditorSupport {
public NacosBooleanEditor() {
}
@Override
public String getJavaInitializationString() {
Object var1 = this.getValue();
return var1 != null ? var1.toString() : "null";
}
@Override
public String getAsText() {
Object var1 = this.getValue();
return var1 instanceof Boolean ? this.getValidName((Boolean) var1) : null;
}
@Override
public void setAsText(String var1) throws IllegalArgumentException {
if (var1 == null) {
this.setValue((Object) null);
}
else if (this.isValidName(true, var1)) {
this.setValue(Boolean.TRUE);
}
else {
if (!this.isValidName(false, var1)) {
throw new IllegalArgumentException(var1);
}
this.setValue(Boolean.FALSE);
}
}
@Override
public String[] getTags() {
return new String[] { this.getValidName(true), this.getValidName(false) };
}
private String getValidName(boolean var1) {
return var1 ? "True" : "False";
}
private boolean isValidName(boolean var1, String var2) {
return this.getValidName(var1).equalsIgnoreCase(var2);
}
}

View File

@ -14,23 +14,33 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.boot.nacos.config.util; package com.alibaba.boot.nacos.config.util.editor;
import java.util.Properties; import java.beans.PropertyEditorSupport;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.boot.bind.RelaxedDataBinder;
/** /**
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a> * @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since 0.1.4 * @since 0.2.3
*/ */
public final class BinderUtils { public class NacosCharSequenceEditor extends PropertyEditorSupport {
public static <T> T bind(T obj, String prefix, Properties properties) { @Override
RelaxedDataBinder binder = new RelaxedDataBinder(obj, prefix); public void setValue(Object value) {
binder.bind(new MutablePropertyValues(properties)); if (value == null) {
return obj; super.setValue("");
}
if (value instanceof CharSequence) {
CharSequence sequence = (CharSequence) value;
super.setValue(sequence.toString());
}
else {
super.setValue(value);
}
} }
@Override
public String getAsText() {
Object value = getValue();
return String.valueOf(value);
}
} }

View File

@ -0,0 +1,107 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.boot.nacos.config.util.editor;
import java.beans.PropertyEditorSupport;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
/**
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since 0.2.3
*/
public class NacosCustomBooleanEditor extends PropertyEditorSupport {
public static final String VALUE_TRUE = "true";
public static final String VALUE_FALSE = "false";
public static final String VALUE_ON = "on";
public static final String VALUE_OFF = "off";
public static final String VALUE_YES = "yes";
public static final String VALUE_NO = "no";
public static final String VALUE_1 = "1";
public static final String VALUE_0 = "0";
@Nullable
private final String trueString;
@Nullable
private final String falseString;
private final boolean allowEmpty;
public NacosCustomBooleanEditor(boolean allowEmpty) {
this(null, null, allowEmpty);
}
public NacosCustomBooleanEditor(@Nullable String trueString,
@Nullable String falseString, boolean allowEmpty) {
this.trueString = trueString;
this.falseString = falseString;
this.allowEmpty = allowEmpty;
}
@Override
public void setValue(Object value) {
super.setValue(convert(String.valueOf(value)));
}
public Object convert(String text) throws IllegalArgumentException {
String input = (text != null ? text.trim() : null);
if (this.allowEmpty && !StringUtils.hasLength(input)) {
// Treat empty String as null value.
return null;
}
else if (this.trueString != null && this.trueString.equalsIgnoreCase(input)) {
return Boolean.TRUE;
}
else if (this.falseString != null && this.falseString.equalsIgnoreCase(input)) {
return Boolean.FALSE;
}
else if (this.trueString == null
&& (VALUE_TRUE.equalsIgnoreCase(input) || VALUE_ON.equalsIgnoreCase(input)
|| VALUE_YES.equalsIgnoreCase(input) || VALUE_1.equals(input))) {
return Boolean.TRUE;
}
else if (this.falseString == null && (VALUE_FALSE.equalsIgnoreCase(input)
|| VALUE_OFF.equalsIgnoreCase(input) || VALUE_NO.equalsIgnoreCase(input)
|| VALUE_0.equals(input))) {
return Boolean.FALSE;
}
else {
throw new IllegalArgumentException("Invalid boolean value [" + text + "]");
}
}
@Override
public String getAsText() {
String t = String.valueOf(getValue());
if (Boolean.TRUE.equals(Boolean.valueOf(t))) {
return (this.trueString != null ? this.trueString : VALUE_TRUE);
}
else if (Boolean.FALSE.equals(Boolean.valueOf(t))) {
return (this.falseString != null ? this.falseString : VALUE_FALSE);
}
else {
return "";
}
}
}

View File

@ -25,11 +25,11 @@ import java.util.List;
/** /**
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a> * @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since 0.1.3 * @since 0.2.3
*/ */
public class NacosEnumEditor implements PropertyEditor { public class NacosEnumEditor implements PropertyEditor {
private final List<PropertyChangeListener> listeners = new ArrayList(); private final List<PropertyChangeListener> listeners = new ArrayList<>(8);
private final Class type; private final Class type;
private final String[] tags; private final String[] tags;
private Object value; private Object value;
@ -153,5 +153,4 @@ public class NacosEnumEditor implements PropertyEditor {
this.listeners.remove(var1); this.listeners.remove(var1);
} }
} }
} }

View File

@ -1,96 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.boot.nacos.config.util.editor;
import java.beans.PropertyEditorSupport;
/**
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since 0.1.3
*/
public class NacosStringEditor extends PropertyEditorSupport {
public NacosStringEditor() {
}
@Override
public String getJavaInitializationString() {
Object var1 = this.getValue();
if (var1 == null) {
return "null";
}
else {
String var2 = var1.toString();
int var3 = var2.length();
StringBuilder var4 = new StringBuilder(var3 + 2);
var4.append('"');
for (int var5 = 0; var5 < var3; ++var5) {
char var6 = var2.charAt(var5);
String var7;
int var8;
switch (var6) {
case '\b':
var4.append("\\b");
continue;
case '\t':
var4.append("\\t");
continue;
case '\n':
var4.append("\\n");
continue;
case '\f':
var4.append("\\f");
continue;
case '\r':
var4.append("\\r");
continue;
case '"':
var4.append("\\\"");
continue;
case '\\':
var4.append("\\\\");
continue;
default:
if (var6 >= ' ' && var6 <= '~') {
var4.append(var6);
continue;
}
var4.append("\\u");
var7 = Integer.toHexString(var6);
var8 = var7.length();
}
while (var8 < 4) {
var4.append('0');
++var8;
}
var4.append(var7);
}
var4.append('"');
return var4.toString();
}
}
@Override
public void setAsText(String var1) {
this.setValue(var1);
}
}

View File

@ -0,0 +1,149 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.boot.nacos.config.util.log;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.boot.nacos.config.util.NacosConfigLoader;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.AbstractListener;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.utils.ConcurrentDiskUtil;
import com.alibaba.nacos.client.config.utils.JvmUtil;
import com.alibaba.nacos.client.logging.NacosLogging;
import com.alibaba.nacos.client.utils.LogUtils;
import com.alibaba.nacos.common.utils.IoUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.spring.util.NacosUtils;
import org.slf4j.Logger;
import org.springframework.boot.context.logging.LoggingApplicationListener;
import org.springframework.boot.logging.LoggingInitializationContext;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.boot.logging.LoggingSystemFactory;
import org.springframework.core.env.ConfigurableEnvironment;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.function.Function;
/**
* Start:
* Step1: get the log XML configuration from the configuration center
* Step2: modify the springboot log configuration path
* Modifying log configuration during operation:
* Clean up the configuration through LoggingSystem and reload the configuration.
*
* @author <a href="mailto:hujun3@xiaomi.com">hujun</a>
*/
public class LogAutoFreshProcess {
private static final Logger LOGGER = LogUtils.logger(LogAutoFreshProcess.class);
private final NacosConfigProperties nacosConfigProperties;
private final ConfigurableEnvironment environment;
private final NacosConfigLoader nacosConfigLoader;
private final Function<Properties, ConfigService> builder;
private static final List<String> LOG_DATA_ID = new ArrayList<>();
private static final String LOG_CACHE_BASE = System.getProperty("JM.SNAPSHOT.PATH", System.getProperty("user.home")) + File.separator + "nacos"
+ File.separator + "logConfig";
static {
LOG_DATA_ID.add("logback.xml");
LOG_DATA_ID.add("log4j2.xml");
}
public static LogAutoFreshProcess build(ConfigurableEnvironment environment, NacosConfigProperties nacosConfigProperties, NacosConfigLoader nacosConfigLoader, Function<Properties, ConfigService> builder) {
return new LogAutoFreshProcess(environment, nacosConfigProperties, nacosConfigLoader, builder);
}
private LogAutoFreshProcess(ConfigurableEnvironment environment, NacosConfigProperties nacosConfigProperties, NacosConfigLoader nacosConfigLoader, Function<Properties, ConfigService> builder) {
this.nacosConfigProperties = nacosConfigProperties;
this.environment = environment;
this.nacosConfigLoader = nacosConfigLoader;
this.builder = builder;
}
public void process() {
final String groupName = environment
.resolvePlaceholders(nacosConfigProperties.getGroup());
ConfigService configService = builder.apply(nacosConfigLoader.getGlobalProperties());
for (String dataId : LOG_DATA_ID) {
String content = NacosUtils.getContent(configService, dataId, groupName);
if (StringUtils.isNotBlank(content)) {
writeLogFile(content, dataId);
System.setProperty(LoggingApplicationListener.CONFIG_PROPERTY, LOG_CACHE_BASE + File.separator + dataId);
registerListener(configService, dataId, groupName);
return;
}
}
}
private void registerListener(ConfigService configService, String dataId, String groupName) {
try {
configService.addListener(dataId, groupName, new AbstractListener() {
@Override
public void receiveConfigInfo(String configInfo) {
if (StringUtils.isNotBlank(configInfo)) {
writeLogFile(configInfo, dataId);
reloadConfig(LOG_CACHE_BASE + File.separator + dataId);
}
}
});
} catch (NacosException e) {
throw new RuntimeException("ConfigService can't add Listener with dataId : " + dataId, e);
}
}
private void writeLogFile(String content, String dataId) {
File file = new File(LOG_CACHE_BASE, dataId);
File parentFile = file.getParentFile();
if (!parentFile.exists()) {
boolean isMdOk = parentFile.mkdirs();
if (!isMdOk) {
LOGGER.error("save log cache error");
}
}
try {
if (JvmUtil.isMultiInstance()) {
ConcurrentDiskUtil.writeFileContent(file, content, Constants.ENCODE);
} else {
IoUtils.writeStringToFile(file, content, Constants.ENCODE);
}
} catch (IOException e) {
throw new RuntimeException("write log file fail");
}
}
private void reloadConfig(String logPath) {
LoggingSystem loggingSystem = LoggingSystemFactory.fromSpringFactories()
.getLoggingSystem(this.getClass().getClassLoader());
loggingSystem.cleanUp();
loggingSystem.initialize(new LoggingInitializationContext(environment),
logPath, null);
NacosLogging.getInstance().loadConfiguration();
}
}

View File

@ -0,0 +1,9 @@
{
"resources": {
"includes": [
{
"pattern": "\\QMETA-INF/services/com.alibaba.nacos.spring.util.ConfigParse\\E"
}
]
}
}

View File

@ -0,0 +1 @@
com.alibaba.boot.nacos.config.support.MultiProfilesYamlConfigParseSupport

View File

@ -1,127 +0,0 @@
{
"hints": [ ],
"groups": [ ],
"properties": [
{
"sourceType": "com.alibaba.boot.nacos.config.properties.NacosConfigProperties",
"name": "nacos.config.enabled",
"description": "enable or disable nacos config feature",
"type": "java.lang.Boolean"
},
{
"sourceType": "com.alibaba.boot.nacos.config.properties.NacosConfigProperties",
"name": "nacos.config.server-addr",
"description": "the server address of nacos",
"type": "java.lang.String"
},
{
"sourceType": "com.alibaba.boot.nacos.config.properties.NacosConfigProperties",
"name": "nacos.config.context-path",
"description": "the context path of nacos server",
"type": "java.lang.String"
},
{
"sourceType": "com.alibaba.boot.nacos.config.properties.NacosConfigProperties",
"name": "nacos.config.encode",
"description": "encode of reading nacos properties",
"type": "java.lang.String"
},
{
"sourceType": "com.alibaba.boot.nacos.config.properties.NacosConfigProperties",
"name": "nacos.config.endpoint",
"description": "the entry domain name of a service in each region",
"type": "java.lang.String"
},
{
"sourceType": "com.alibaba.boot.nacos.config.properties.NacosConfigProperties",
"name": "nacos.config.namespace",
"description": "for configuration isolation by tenants. Different namespaces may have configurations with the same Group or Data ID. ",
"type": "java.lang.String"
},
{
"sourceType": "com.alibaba.boot.nacos.config.properties.NacosConfigProperties",
"name": "nacos.config.access-key",
"description": "the accesskey of Alibaba Cloud Account",
"type": "java.lang.String"
},
{
"sourceType": "com.alibaba.boot.nacos.config.properties.NacosConfigProperties",
"name": "nacos.config.secret-key",
"description": "the secretkey of Alibaba Cloud Account",
"type": "java.lang.String"
},
{
"sourceType": "com.alibaba.boot.nacos.config.properties.NacosConfigProperties",
"name": "nacos.config.ram-role-name",
"description": "the ramRoleName of Alibaba Cloud Account",
"type": "java.lang.String"
},
{
"sourceType": "com.alibaba.boot.nacos.config.properties.NacosConfigProperties",
"name": "nacos.config.data-id",
"type": "java.lang.String"
},
{
"sourceType": "com.alibaba.boot.nacos.config.properties.NacosConfigProperties",
"name": "nacos.config.data-ids",
"type": "java.lang.String"
},
{
"sourceType": "com.alibaba.boot.nacos.config.properties.NacosConfigProperties",
"name": "nacos.config.group",
"type": "java.lang.String"
},
{
"sourceType": "com.alibaba.boot.nacos.config.properties.NacosConfigProperties",
"name": "nacos.config.auto-refresh",
"type": "java.lang.Boolean"
},
{
"sourceType": "com.alibaba.boot.nacos.config.properties.NacosConfigProperties",
"name": "nacos.config.max-retry",
"description": "the secretkey of Alibaba Cloud Account",
"type": "java.lang.String"
},
{
"sourceType": "com.alibaba.boot.nacos.config.properties.NacosConfigProperties",
"name": "nacos.config.config-long-poll-timeout",
"description": "the secretkey of Alibaba Cloud Account",
"type": "java.lang.String"
},
{
"sourceType": "com.alibaba.boot.nacos.config.properties.NacosConfigProperties",
"name": "nacos.config.config-retry-time",
"description": "the secretkey of Alibaba Cloud Account",
"type": "java.lang.String"
},
{
"sourceType": "com.alibaba.boot.nacos.config.properties.NacosConfigProperties",
"name": "nacos.config.type",
"description": "the secretkey of Alibaba Cloud Account",
"type": "com.alibaba.nacos.api.config.ConfigType"
},{
"sourceType": "com.alibaba.boot.nacos.config.properties.NacosConfigProperties",
"name": "nacos.config.enable-remote-sync-config",
"description": "the secretkey of Alibaba Cloud Account",
"type": "java.lang.Boolean"
},
{
"sourceType": "com.alibaba.boot.nacos.config.properties.NacosConfigProperties",
"name": "nacos.config.bootstrap.enable",
"description": "the secretkey of Alibaba Cloud Account",
"type": "java.lang.String"
},
{
"sourceType": "com.alibaba.boot.nacos.config.properties.NacosConfigProperties",
"name": "nacos.config.bootstrap.log.enable",
"description": "the secretkey of Alibaba Cloud Account",
"type": "java.lang.String"
},
{
"sourceType": "com.alibaba.boot.nacos.config.properties.NacosConfigProperties",
"name": "nacos.config.ext-config",
"description": "the secretkey of Alibaba Cloud Account",
"type": "java.util.List<com.alibaba.boot.nacos.config.properties.NacosConfigProperties.Config>"
}
]
}

View File

@ -1,4 +1,9 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration
#org.springframework.context.ApplicationContextInitializer=\
# com.alibaba.boot.nacos.config.autoconfigure.NacosConfigApplicationContextInitializer
org.springframework.boot.env.EnvironmentPostProcessor=\ org.springframework.boot.env.EnvironmentPostProcessor=\
com.alibaba.boot.nacos.config.autoconfigure.NacosConfigEnvironmentProcessor com.alibaba.boot.nacos.config.autoconfigure.NacosConfigEnvironmentProcessor,\
com.alibaba.boot.nacos.config.support.MultiProfilesYamlConfigParseSupport
org.springframework.context.ApplicationListener=\
com.alibaba.boot.nacos.config.logging.NacosLoggingListener

View File

@ -0,0 +1,4 @@
com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration
com.alibaba.boot.nacos.config.autoconfigure.NacosConfigEnvironmentProcessor
com.alibaba.boot.nacos.config.support.MultiProfilesYamlConfigParseSupport
com.alibaba.boot.nacos.config.logging.NacosLoggingListener

View File

@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.boot.nacos.autoconfigure;
import com.alibaba.boot.nacos.config.autoconfigure.NacosBootConfigException;
import org.junit.Assert;
import org.junit.Test;
/**
* {@link NacosBootConfigException} Test
* @ClassName: NacosBootConfigExceptionTest
* @Author: ChenHao26
* @Date: 2022/8/12 15:56
*/
public class NacosBootConfigExceptionTest {
@Test
public void getCons() {
try {
testMethod("spring boot");
}catch (Exception e) {
Assert.assertTrue(e instanceof NacosBootConfigException);
}
}
private void testMethod(String str) {
if (str.startsWith("spring")) {
throw new NacosBootConfigException(new Throwable());
}
}
}

View File

@ -0,0 +1,79 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.boot.nacos.autoconfigure;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigApplicationContextInitializer;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigBootBeanDefinitionRegistrar;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigEnvironmentProcessor;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.boot.nacos.config.util.NacosConfigLoader;
import com.alibaba.boot.nacos.config.util.NacosConfigLoaderFactory;
import com.alibaba.boot.nacos.config.util.NacosConfigPropertiesUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* {@link NacosConfigApplicationContextInitializer} Test
* @ClassName: NacosConfigApplicationContextInitializerTest
* @Author: ChenHao26
* @Date: 2022/8/12 15:25
*/
@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(properties = { "nacos.config.server-addr=localhost" })
@SpringBootTest(classes = { NacosConfigAutoConfiguration.class })
public class NacosConfigApplicationContextInitializerTest {
private NacosConfigApplicationContextInitializer nacosConfigApplicationContextInitializer;
@Autowired
private ConfigurableEnvironment environment;
@Autowired
private NacosConfigProperties nacosConfigProperties;
@Autowired
private ConfigurableApplicationContext context;
@Before
public void testNacosConfigApplicationContextInitializer() {
nacosConfigApplicationContextInitializer = new NacosConfigApplicationContextInitializer(new NacosConfigEnvironmentProcessor());
}
@Test
public void initialize(){
try {
nacosConfigProperties = NacosConfigPropertiesUtils
.buildNacosConfigProperties(environment);
Assert.assertNotNull(nacosConfigProperties);
NacosConfigLoader singleton = NacosConfigLoaderFactory.getSingleton(null);
Assert.assertNotNull(singleton);
nacosConfigApplicationContextInitializer.initialize(context);
} catch (Exception e) {
Assert.assertNotNull(e);
}
}
}

View File

@ -19,6 +19,7 @@ package com.alibaba.boot.nacos.autoconfigure;
import java.util.Properties; import java.util.Properties;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration; import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration;
import com.alibaba.boot.nacos.config.binder.NacosBootConfigurationPropertiesBinder;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties; import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.nacos.api.PropertyKeyConst; import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.annotation.NacosInjected; import com.alibaba.nacos.api.annotation.NacosInjected;
@ -63,9 +64,9 @@ public class NacosConfigAutoConfigurationTest {
Assert.assertEquals("localhost", nacosConfigProperties.getServerAddr()); Assert.assertEquals("localhost", nacosConfigProperties.getServerAddr());
} }
@Test(expected = NoSuchBeanDefinitionException.class) @Test
public void testNacosConfigGlobalBean() { public void testNacosConfigGlobalBean() {
Assert.assertNull(applicationContext Assert.assertNotNull(applicationContext
.getBean(NacosBeanUtils.GLOBAL_NACOS_PROPERTIES_BEAN_NAME)); .getBean(NacosBeanUtils.GLOBAL_NACOS_PROPERTIES_BEAN_NAME));
} }
@ -84,4 +85,8 @@ public class NacosConfigAutoConfigurationTest {
properties.getProperty(PropertyKeyConst.SERVER_ADDR)); properties.getProperty(PropertyKeyConst.SERVER_ADDR));
} }
@Test
public void testNacosConfigBootBeanDefinitionRegistrar() {
Assert.assertNotNull(applicationContext.getBean(NacosBootConfigurationPropertiesBinder.BEAN_NAME));
}
} }

View File

@ -0,0 +1,69 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.boot.nacos.autoconfigure;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigBootBeanDefinitionRegistrar;
import com.alibaba.boot.nacos.config.binder.NacosBootConfigurationPropertiesBinder;
import com.alibaba.nacos.client.utils.LogUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* {@link NacosConfigBootBeanDefinitionRegistrar} Test
* @ClassName: NacosConfigBootBeanDefinitionRegistrarTest
* @Author: ChenHao26
* @Date: 2022/8/12 15:38
*/
@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(properties = { "nacos.config.server-addr=localhost" })
@SpringBootTest(classes = { NacosConfigAutoConfiguration.class })
public class NacosConfigBootBeanDefinitionRegistrarTest {
private static final Logger LOGGER = LogUtils.logger(NacosConfigBootBeanDefinitionRegistrarTest.class);
private NacosConfigBootBeanDefinitionRegistrar nacosConfigBootBeanDefinitionRegistrar;
@Before
public void setup() {
nacosConfigBootBeanDefinitionRegistrar = new NacosConfigBootBeanDefinitionRegistrar();
}
@Test
public void setBeanFactory(){
try {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition("beanName");
Assert.assertNotNull(builder);
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
nacosConfigBootBeanDefinitionRegistrar.setBeanFactory(beanFactory);
Assert.assertNotNull(beanFactory.getBeanDefinition(NacosBootConfigurationPropertiesBinder.BEAN_NAME));
nacosConfigBootBeanDefinitionRegistrar.setBeanFactory(beanFactory);
}catch (Exception e) {
LOGGER.error("error info: {}",e.toString());
Assert.assertNull(e);
}
}
}

View File

@ -0,0 +1,85 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.boot.nacos.autoconfigure;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigEnvironmentProcessor;
import com.alibaba.boot.nacos.config.binder.NacosBootConfigurationPropertiesBinder;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.boot.nacos.config.util.NacosConfigPropertiesUtils;
import com.alibaba.nacos.client.config.NacosConfigService;
import com.alibaba.nacos.client.utils.LogUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* {@link NacosBootConfigurationPropertiesBinder} Test
* @ClassName: NacosConfigEnvironmentProcessorTest
* @Author: ChenHao26
* @Date: 2022/8/12 15:43
*/
@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(properties = { "nacos.config.server-addr=localhost" })
@SpringBootTest(classes = { NacosConfigAutoConfiguration.class })
public class NacosConfigEnvironmentProcessorTest {
private NacosConfigEnvironmentProcessor nacosConfigEnvironmentProcessor;
@Autowired
private ConfigurableEnvironment environment;
private static final Logger LOGGER = LogUtils.logger(NacosConfigEnvironmentProcessorTest.class);
@Mock
private NacosConfigProperties nacosConfigProperties;
@Before
public void setup() {
nacosConfigEnvironmentProcessor = new NacosConfigEnvironmentProcessor();
}
@Test
public void postProcessEnvironment() {
try {
NacosConfigProperties nacosConfigProperties1 = NacosConfigPropertiesUtils.buildNacosConfigProperties(
environment);
Assert.assertFalse(nacosConfigProperties1.isEnableRemoteSyncConfig());
nacosConfigEnvironmentProcessor.postProcessEnvironment(environment, new SpringApplication());
}catch (Exception e) {
LOGGER.error("error info :{} ",e);
Assert.assertNull(e);
}
}
@Test
public void getOrder() {
int order = nacosConfigEnvironmentProcessor.getOrder();
Assert.assertNotNull(order);
}
}

View File

@ -0,0 +1,108 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.boot.nacos.binder;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration;
import com.alibaba.boot.nacos.config.binder.NacosBootConfigurationPropertiesBinder;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.annotation.NacosConfigurationProperties;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.spring.context.event.config.EventPublishingConfigService;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.lang.reflect.Method;
/**
* {@link NacosBootConfigurationPropertiesBinder} Test
* @ClassName: NacosBootConfigurationPropertiesBinderTest
* @Author: ChenHao26
* @Date: 2022/8/12 16:00
*/
@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(properties = { "nacos.config.server-addr=localhost" })
@SpringBootTest(classes = { NacosConfigAutoConfiguration.class })
public class NacosBootConfigurationPropertiesBinderTest {
private Binder binder;
@Autowired
private ConfigurableApplicationContext context;
@Before
public void setup() {
binder = new Binder(context);
}
@Test
public void findFactoryMethod(){
Method beanName = binder.findFactoryMethod(NacosBootConfigurationPropertiesBinder.BEAN_NAME);
Assert.assertNull(beanName);
}
@Test
public void testDoBind() {
People people = new People();
binder.doBind(people, "people", "people", "people", "properties",
People.class.getAnnotation(NacosConfigurationProperties.class), "people.name=SuperZ1999\npeople.age=24",
new EventPublishingConfigService(null, null, context, null));
Assert.assertEquals(people.getName(), "SuperZ1999");
Assert.assertEquals(people.getAge(), 24);
}
static class Binder extends NacosBootConfigurationPropertiesBinder {
public Binder(ConfigurableApplicationContext applicationContext) {
super(applicationContext);
}
@Override
protected void doBind(Object bean, String beanName, String dataId, String groupId, String configType, NacosConfigurationProperties properties, String content, ConfigService configService) {
super.doBind(bean, beanName, dataId, groupId, configType, properties, content, configService);
}
}
@NacosConfigurationProperties(prefix = "people", dataId = "people", groupId = "people")
static class People {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
}

View File

@ -0,0 +1,162 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.boot.nacos.config.support;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration;
import com.alibaba.nacos.spring.util.ConfigParseUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.env.Environment;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* {@link MultiProfilesYamlConfigParseSupport} Test
*
* @author <a href="mailto:yanglu_u@126.com">dbses</a>
*/
public class MultiProfilesYamlConfigParseSupportTest {
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles({"alpha"})
@SpringBootTest(classes = {NacosConfigAutoConfiguration.class})
public static class OneProfiles {
@Autowired
private Environment environment;
@Before
public void setUp() {
// because MultiProfilesYamlConfigParseSupport # postProcessEnvironment() run once,
// so it should set profilesArray before test
MultiProfilesYamlConfigParseSupport.setProfileArray(environment.getActiveProfiles());
}
@Test
public void oneProfiles_normal() {
String content = "test1:\n" +
" config: 2\n" +
"\n" +
"---\n" +
"spring:\n" +
" profiles: alpha\n" +
"test1:\n" +
" config: alpha\n" +
"\n" +
"---\n" +
"spring:\n" +
" profiles: beta\n" +
"test1:\n" +
" config: beta";
Assert.assertEquals(environment.getActiveProfiles()[0], "alpha");
Object result = ConfigParseUtils.toProperties("test.yaml", "test", content, "yaml")
.get("test1.config");
Assert.assertEquals("alpha", result);
}
@Test
public void oneProfiles_when_content_profiles_isnull() {
String content = "test1:\n" +
" config: 2\n" +
"\n" +
"---\n" +
"test1:\n" +
" config: alpha\n" +
"\n" +
"---\n" +
"test1:\n" +
" config: beta";
Object result = ConfigParseUtils.toProperties("test.yaml", "test", content, "yaml")
.get("test1.config");
Assert.assertEquals("beta", result);
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles({"alpha", "beta"})
@SpringBootTest(classes = {NacosConfigAutoConfiguration.class})
public static class TwoProfiles {
@Autowired
private Environment environment;
@Before
public void setUp() {
MultiProfilesYamlConfigParseSupport.setProfileArray(environment.getActiveProfiles());
}
@Test
public void twoProfiles_normal() {
String content = "test1:\n" +
" config: 2\n" +
"\n" +
"---\n" +
"spring:\n" +
" profiles: alpha\n" +
"test1:\n" +
" config: alpha\n" +
"\n" +
"---\n" +
"spring:\n" +
" profiles: beta\n" +
"test1:\n" +
" config: beta";
Assert.assertEquals(environment.getActiveProfiles()[0], "alpha");
Assert.assertEquals(environment.getActiveProfiles()[1], "beta");
Object result = ConfigParseUtils.toProperties("test.yaml", "test", content, "yaml")
.get("test1.config");
Assert.assertEquals("beta", result);
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {NacosConfigAutoConfiguration.class})
public static class NoProfiles {
@Autowired
private Environment environment;
@Test
public void noProfiles_normal() {
String content = "test1:\n" +
" config: 2\n" +
"\n" +
"---\n" +
"spring:\n" +
" profiles: default\n" +
"test1:\n" +
" config: default\n" +
"\n" +
"---\n" +
"spring:\n" +
" profiles: beta\n" +
"test1:\n" +
" config: beta";
Assert.assertEquals(environment.getActiveProfiles().length, 0);
Object result = ConfigParseUtils.toProperties("test.yaml", "test", content, "yaml")
.get("test1.config");
Assert.assertEquals("default", result);
}
}
}

View File

@ -0,0 +1,59 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.boot.nacos.logging;
import com.alibaba.boot.nacos.config.logging.NacosLoggingListener;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.core.ResolvableType;
import java.lang.reflect.Type;
/**
* {@link NacosLoggingListener} Test
* @ClassName: AttributeExtractTaskTest
* @Author: ChenHao26
* @Date: 2022/8/12 15:08
*/
public class NacosLoggingListenerTest {
private NacosLoggingListener nacosLoggingListener;
@Before
public void setup() {
nacosLoggingListener = new NacosLoggingListener();
}
@Test
public void supportsEventType() {
boolean result = nacosLoggingListener.supportsEventType(ResolvableType.forType(new Type() {
@Override
public String getTypeName() {
return Type.super.getTypeName();
}
}));
Assert.assertEquals(result, false);
}
@Test
public void getOrder() {
int order = nacosLoggingListener.getOrder();
Assert.assertNotNull(order);
}
}

View File

@ -0,0 +1,65 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.boot.nacos.util;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration;
import com.alibaba.boot.nacos.config.util.AttributeExtractTask;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySources;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.Map;
/**
* {@link AttributeExtractTask} Test
* @ClassName: AttributeExtractTaskTest
* @Author: ChenHao26
* @Date: 2022/8/12 15:08
*/
@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(properties = { "nacos.config.server-addr=localhost" })
@SpringBootTest(classes = { NacosConfigAutoConfiguration.class })
public class AttributeExtractTaskTest {
private AttributeExtractTask attributeExtractTask;
@Autowired
private ConfigurableEnvironment environment ;
@Before
public void setUp() {
environment.setDefaultProfiles("prefix01");
attributeExtractTask = new AttributeExtractTask("nacos.config",environment);
}
@Test
public void call() throws Exception{
Map<String, String> map = attributeExtractTask.call();
Assert.assertEquals(map.get("nacos.config.server-addr"), "localhost");
}
}

View File

@ -0,0 +1,87 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.boot.nacos.util;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.boot.nacos.config.util.NacosConfigLoader;
import com.alibaba.boot.nacos.config.util.NacosConfigLoaderFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.ConfigType;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.NacosConfigService;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.Properties;
import java.util.function.Function;
/**
* @ClassName: NacosConfigLoaderFactoryTest
* @Author: ChenHao26
* @Date: 2022/8/12 16:42
*/
@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(properties = { "nacos.config.server-addr=localhost" })
@SpringBootTest(classes = { NacosConfigAutoConfiguration.class })
public class NacosConfigLoaderFactoryTest {
private NacosConfigProperties nacosConfigProperties;
private Properties globalProperties;
private Function<Properties, ConfigService> builder;
@Before
public void setup() {
nacosConfigProperties = new NacosConfigProperties();
nacosConfigProperties.setServerAddr("localhost");
nacosConfigProperties.setUsername("nacos");
nacosConfigProperties.setPassword("nacos");
nacosConfigProperties.setMaxRetry("4");
nacosConfigProperties.setType(ConfigType.TEXT);
nacosConfigProperties.setDataId("xiaomi");
nacosConfigProperties.setGroup("group01");
nacosConfigProperties.setAutoRefresh(true);
nacosConfigProperties.setEndpoint("localhost");
globalProperties = new Properties();
globalProperties.setProperty("maxRetry","3");
globalProperties.setProperty("content","key=01");
globalProperties.setProperty("endpoint","localhost");
builder = properties -> {
try {
return new NacosConfigService(globalProperties);
} catch (NacosException e) {
throw new RuntimeException(e);
}
};
}
@Test
public void getSingleton() {
NacosConfigLoader singleton = NacosConfigLoaderFactory.getSingleton(builder);
NacosConfigLoader singleton2 = NacosConfigLoaderFactory.getSingleton(builder);
// Verify that it is the same object
Assert.assertEquals(singleton2, singleton);
}
}

View File

@ -0,0 +1,116 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.boot.nacos.util;
import com.alibaba.boot.nacos.autoconfigure.NacosConfigEnvironmentProcessorTest;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.boot.nacos.config.util.NacosConfigLoader;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.ConfigType;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.NacosConfigService;
import com.alibaba.nacos.client.utils.LogUtils;
import com.alibaba.nacos.spring.core.env.NacosPropertySourcePostProcessor;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.function.Function;
/**
* @ClassName: NacosConfigLoaderTest
* @Author: ChenHao26
* @Date: 2022/8/12 16:12
*/
@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(properties = { "nacos.config.server-addr=localhost" })
@SpringBootTest(classes = { NacosConfigAutoConfiguration.class })
public class NacosConfigLoaderTest {
private NacosConfigLoader nacosConfigLoader;
private NacosConfigProperties nacosConfigProperties;
private Properties globalProperties;
@Autowired
private ConfigurableEnvironment environment;
private Function<Properties, ConfigService> builder;
private List<NacosConfigLoader.DeferNacosPropertySource> nacosPropertySources;
private static final Logger LOGGER = LogUtils.logger(NacosConfigEnvironmentProcessorTest.class);
private NacosPropertySourcePostProcessor nacosPropertySourcePostProcessor;
@Before
public void setup() {
nacosConfigProperties = new NacosConfigProperties();
nacosConfigProperties.setServerAddr("localhost");
nacosConfigProperties.setUsername("nacos");
nacosConfigProperties.setPassword("nacos");
nacosConfigProperties.setMaxRetry("4");
nacosConfigProperties.setType(ConfigType.TEXT);
nacosConfigProperties.setDataId("xiaomi");
nacosConfigProperties.setGroup("group01");
nacosConfigProperties.setAutoRefresh(true);
nacosConfigProperties.setEndpoint("localhost");
globalProperties = new Properties();
globalProperties.setProperty("maxRetry","3");
globalProperties.setProperty("content","key=01");
globalProperties.setProperty("endpoint","localhost");
builder = properties -> {
try {
return new NacosConfigService(globalProperties);
} catch (NacosException e) {
throw new RuntimeException(e);
}
};
nacosPropertySources = new LinkedList<>();
nacosConfigLoader = new NacosConfigLoader(builder);
nacosPropertySourcePostProcessor = new NacosPropertySourcePostProcessor();
}
@Test
public void buildGlobalNacosProperties() {
Properties properties = nacosConfigLoader.buildGlobalNacosProperties(environment, nacosConfigProperties);
LOGGER.info("buildGlobalNacosProperties properties : {}", properties);
Assert.assertNotNull(properties);
Assert.assertEquals(properties.size(), 6);
}
@Test
public void addListenerIfAutoRefreshed() {
nacosConfigLoader.addListenerIfAutoRefreshed();
List<NacosConfigLoader.DeferNacosPropertySource> propertySources = nacosConfigLoader.getNacosPropertySources();
Assert.assertEquals(propertySources.size(), 0);
}
}

View File

@ -0,0 +1,56 @@
/*
*
* * Licensed to the Apache Software Foundation (ASF) under one or more
* * contributor license agreements. See the NOTICE file distributed with
* * this work for additional information regarding copyright ownership.
* * The ASF licenses this file to You under the Apache License, Version 2.0
* * (the "License"); you may not use this file except in compliance with
* * the License. You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*/
package com.alibaba.boot.nacos.util;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.boot.nacos.config.util.NacosConfigPropertiesUtils;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* {@link NacosConfigPropertiesUtils} Test
* @ClassName: NacosConfigPropertiesUtilsTest
* @Author: SuperZ1999
* @Date: 2023/9/28
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = { NacosConfigAutoConfiguration.class })
@TestPropertySource(properties = {
"nacos.config.server-addr=8.8.8.8",
"nacos.config.password=123456"
})
public class NacosConfigPropertiesUtilsTest {
@Autowired
private ConfigurableEnvironment environment;
@Test
public void testBuildNacosConfigProperties() {
NacosConfigProperties properties = NacosConfigPropertiesUtils.buildNacosConfigProperties(environment);
Assert.assertEquals(properties.getServerAddr(), "8.8.8.8");
Assert.assertEquals(properties.getPassword(), "123456");
}
}

View File

@ -0,0 +1,78 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.boot.nacos.util;
import com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration;
import com.alibaba.boot.nacos.config.util.NacosPropertiesBuilder;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.env.Environment;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.Properties;
/**
* @ClassName: NacosPropertiesBuilderTest
* @Author: ChenHao26
* @Date: 2022/8/12 16:49
*/
@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(properties = { "nacos.config.server-addr=localhost" })
@SpringBootTest(classes = { NacosConfigAutoConfiguration.class })
public class NacosPropertiesBuilderTest {
@Autowired
private Environment environment;
@Test
public void testBuildNacosProperties() {
String serverAddr = "${nacos.config.server-addr}";
String namespaceId = "namespaceId";
String secretKey = "secretKey";
String ramRoleName = "ramRoleName";
String configLongPollTimeout = "configLongPollTimeout";
String configRetryTimeout = "configRetryTimeout";
String maxRetry = "maxRetry";
String enableRemoteSyncConfig = "enableRemoteSyncConfig";
String username = "nacos";
String password = "password";
Properties properties = NacosPropertiesBuilder.buildNacosProperties(environment, serverAddr, namespaceId, secretKey,
"ak", ramRoleName, configLongPollTimeout, configRetryTimeout, maxRetry, null,enableRemoteSyncConfig, true,
username, password);
Assert.assertEquals(properties.size(), 12);
Assert.assertEquals(properties.get("serverAddr"), "localhost");
}
@Test
public void testMerge() {
Properties sourceProperties = new Properties();
sourceProperties.put("name", "SuperZ1999");
sourceProperties.put("age", 24);
Properties targetProperties = new Properties();
targetProperties.put("age", 99);
NacosPropertiesBuilder.merge(targetProperties, sourceProperties);
Assert.assertEquals(targetProperties.get("name"), "SuperZ1999");
Assert.assertEquals(targetProperties.get("age"), 99);
}
}

View File

@ -0,0 +1,51 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.boot.nacos.util.editor;
import com.alibaba.boot.nacos.config.util.editor.NacosCharSequenceEditor;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* @ClassName: NacosCharSequenceEditorTest
* @Author: ChenHao26
* @Date: 2022/8/12 17:00
*/
public class NacosCharSequenceEditorTest {
public NacosCharSequenceEditor nacosCharSequenceEditor;
@Before
public void setup() {
nacosCharSequenceEditor = new NacosCharSequenceEditor();
}
@Test
public void setValue() {
nacosCharSequenceEditor.setValue("nacosTest");
String asText = nacosCharSequenceEditor.getAsText();
Assert.assertEquals(asText,"nacosTest");
}
@Test
public void getAsText() {
String str = nacosCharSequenceEditor.getAsText();
Assert.assertEquals(str, "null");
}
}

View File

@ -0,0 +1,64 @@
/*
*
* * Licensed to the Apache Software Foundation (ASF) under one or more
* * contributor license agreements. See the NOTICE file distributed with
* * this work for additional information regarding copyright ownership.
* * The ASF licenses this file to You under the Apache License, Version 2.0
* * (the "License"); you may not use this file except in compliance with
* * the License. You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*/
package com.alibaba.boot.nacos.util.editor;
import com.alibaba.boot.nacos.config.util.editor.NacosCustomBooleanEditor;
import org.junit.Assert;
import org.junit.Test;
/**
* {@link NacosCustomBooleanEditor} Test
* @ClassName: NacosCustomBooleanEditorTest
* @Author: SuperZ1999
* @Date: 2023/9/28
*/
public class NacosCustomBooleanEditorTest {
@Test
public void testAllowEmpty() {
NacosCustomBooleanEditor booleanEditor = new NacosCustomBooleanEditor(true);
booleanEditor.setValue("");
Assert.assertEquals(booleanEditor.getAsText(), "false");
booleanEditor.setValue("true");
Assert.assertEquals(booleanEditor.getAsText(), "true");
}
@Test(expected = IllegalArgumentException.class)
public void testNotAllowEmpty() {
NacosCustomBooleanEditor booleanEditor = new NacosCustomBooleanEditor(false);
booleanEditor.setValue("true");
Assert.assertEquals(booleanEditor.getAsText(), "true");
booleanEditor.setValue("");
}
@Test
public void testCustomBooleanString() {
NacosCustomBooleanEditor booleanEditor = new NacosCustomBooleanEditor("TRUE", "FALSE", true);
booleanEditor.setValue("");
Assert.assertEquals(booleanEditor.getAsText(), "FALSE");
booleanEditor.setValue("TRUE");
Assert.assertEquals(booleanEditor.getAsText(), "TRUE");
booleanEditor.setValue("false");
Assert.assertEquals(booleanEditor.getAsText(), "FALSE");
}
}

View File

@ -18,7 +18,7 @@
<parent> <parent>
<groupId>com.alibaba.boot</groupId> <groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-parent</artifactId> <artifactId>nacos-spring-boot-parent</artifactId>
<version>0.1.4</version> <version>${revision}</version>
<relativePath>../nacos-spring-boot-parent</relativePath> <relativePath>../nacos-spring-boot-parent</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -34,13 +34,24 @@
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId> <artifactId>spring-boot-starter</artifactId>
<scope>true</scope>
</dependency> </dependency>
<!-- Nacos --> <!-- Nacos -->
<dependency> <dependency>
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId> <artifactId>nacos-spring-context</artifactId>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${nacos.version}</version>
</dependency> </dependency>
<dependency> <dependency>
@ -53,5 +64,10 @@
<artifactId>nacos-spring-boot-base</artifactId> <artifactId>nacos-spring-boot-base</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-aot</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -18,7 +18,7 @@
<parent> <parent>
<artifactId>nacos-spring-boot-parent</artifactId> <artifactId>nacos-spring-boot-parent</artifactId>
<groupId>com.alibaba.boot</groupId> <groupId>com.alibaba.boot</groupId>
<version>0.1.4</version> <version>${revision}</version>
<relativePath>../nacos-spring-boot-parent/pom.xml</relativePath> <relativePath>../nacos-spring-boot-parent/pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -81,8 +81,21 @@
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId> <artifactId>nacos-spring-context</artifactId>
<optional>true</optional> <optional>true</optional>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${nacos.version}</version>
</dependency>
<!-- Test Dependencies --> <!-- Test Dependencies -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>

View File

@ -16,12 +16,9 @@
*/ */
package com.alibaba.boot.nacos.discovery.actuate.autoconfigure; package com.alibaba.boot.nacos.discovery.actuate.autoconfigure;
import com.alibaba.boot.nacos.discovery.NacosDiscoveryConstants;
import com.alibaba.boot.nacos.discovery.actuate.endpoint.NacosDiscoveryEndpoint; import com.alibaba.boot.nacos.discovery.actuate.endpoint.NacosDiscoveryEndpoint;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
import org.springframework.boot.actuate.condition.ConditionalOnEnabledEndpoint; import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.Endpoint;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -33,12 +30,11 @@ import org.springframework.context.annotation.Configuration;
* @see Endpoint * @see Endpoint
*/ */
@Configuration @Configuration
@ConditionalOnClass(Endpoint.class)
public class NacosDiscoveryEndpointsAutoConfiguration { public class NacosDiscoveryEndpointsAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
@ConditionalOnEnabledEndpoint(NacosDiscoveryConstants.ENDPOINT_PREFIX) @ConditionalOnAvailableEndpoint
public NacosDiscoveryEndpoint nacosDiscoveryEndpoint() { public NacosDiscoveryEndpoint nacosDiscoveryEndpoint() {
return new NacosDiscoveryEndpoint(); return new NacosDiscoveryEndpoint();
} }

View File

@ -20,8 +20,8 @@ import com.alibaba.boot.nacos.discovery.NacosDiscoveryConstants;
import com.alibaba.boot.nacos.discovery.actuate.health.NacosDiscoveryHealthIndicator; import com.alibaba.boot.nacos.discovery.actuate.health.NacosDiscoveryHealthIndicator;
import com.alibaba.boot.nacos.discovery.autoconfigure.NacosDiscoveryAutoConfiguration; import com.alibaba.boot.nacos.discovery.autoconfigure.NacosDiscoveryAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.ConditionalOnEnabledHealthIndicator; import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.AutoConfigureBefore;

View File

@ -22,16 +22,17 @@ import java.util.Properties;
import com.alibaba.boot.nacos.common.PropertiesUtils; import com.alibaba.boot.nacos.common.PropertiesUtils;
import com.alibaba.boot.nacos.discovery.NacosDiscoveryConstants; import com.alibaba.boot.nacos.discovery.NacosDiscoveryConstants;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.naming.NamingService; import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.spring.factory.CacheableEventPublishingNacosServiceFactory; import com.alibaba.nacos.spring.factory.CacheableEventPublishingNacosServiceFactory;
import com.alibaba.nacos.spring.factory.NacosServiceFactory; import com.alibaba.nacos.spring.factory.NacosServiceFactory;
import com.alibaba.nacos.spring.util.NacosUtils; import com.alibaba.nacos.spring.util.NacosUtils;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.endpoint.AbstractEndpoint; import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import static com.alibaba.nacos.spring.util.NacosBeanUtils.DISCOVERY_GLOBAL_NACOS_PROPERTIES_BEAN_NAME; import static com.alibaba.nacos.spring.util.NacosBeanUtils.DISCOVERY_GLOBAL_NACOS_PROPERTIES_BEAN_NAME;
@ -42,18 +43,15 @@ import static com.alibaba.nacos.spring.util.NacosBeanUtils.DISCOVERY_GLOBAL_NACO
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a> * @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
* @see Endpoint * @see Endpoint
*/ */
public class NacosDiscoveryEndpoint extends AbstractEndpoint<Map<String, Object>> { @Endpoint(id = NacosDiscoveryConstants.ENDPOINT_PREFIX)
public class NacosDiscoveryEndpoint {
@Autowired @Autowired
private ApplicationContext applicationContext; private ApplicationContext applicationContext;
private static final Integer PAGE_SIZE = 100; private static final Integer PAGE_SIZE = 100;
public NacosDiscoveryEndpoint() { @ReadOperation
super(NacosDiscoveryConstants.ENDPOINT_PREFIX);
}
@Override
public Map<String, Object> invoke() { public Map<String, Object> invoke() {
Map<String, Object> result = new HashMap<>(8); Map<String, Object> result = new HashMap<>(8);
@ -63,19 +61,18 @@ public class NacosDiscoveryEndpoint extends AbstractEndpoint<Map<String, Object>
NacosServiceFactory nacosServiceFactory = CacheableEventPublishingNacosServiceFactory NacosServiceFactory nacosServiceFactory = CacheableEventPublishingNacosServiceFactory
.getSingleton(); .getSingleton();
;
JSONArray array = new JSONArray(); ArrayNode array = JacksonUtils.createEmptyArrayNode();
for (NamingService namingService : nacosServiceFactory.getNamingServices()) { for (NamingService namingService : nacosServiceFactory.getNamingServices()) {
JSONObject jsonObject = new JSONObject(); ObjectNode jsonObject = JacksonUtils.createEmptyJsonNode();
try { try {
jsonObject.put("servicesOfServer", jsonObject.putPOJO("servicesOfServer",
namingService.getServicesOfServer(0, PAGE_SIZE)); namingService.getServicesOfServer(0, PAGE_SIZE));
jsonObject.put("subscribeServices", namingService.getSubscribeServices()); jsonObject.putPOJO("subscribeServices", namingService.getSubscribeServices());
array.add(jsonObject); array.add(jsonObject);
} }
catch (Exception e) { catch (Exception e) {
jsonObject.put("serverStatus", namingService.getServerStatus() jsonObject.put("serverStatus", namingService.getServerStatus() + ": "
+ NacosUtils.SEPARATOR + e.getMessage()); + NacosUtils.SEPARATOR + e.getMessage());
} }
} }

View File

@ -19,8 +19,8 @@ package com.alibaba.boot.nacos.discovery.actuate.health;
import java.util.Properties; import java.util.Properties;
import com.alibaba.boot.nacos.common.PropertiesUtils; import com.alibaba.boot.nacos.common.PropertiesUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.naming.NamingService; import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.spring.factory.CacheableEventPublishingNacosServiceFactory; import com.alibaba.nacos.spring.factory.CacheableEventPublishingNacosServiceFactory;
import com.alibaba.nacos.spring.factory.NacosServiceFactory; import com.alibaba.nacos.spring.factory.NacosServiceFactory;
import com.alibaba.nacos.spring.metadata.NacosServiceMetaData; import com.alibaba.nacos.spring.metadata.NacosServiceMetaData;
@ -54,11 +54,11 @@ public class NacosDiscoveryHealthIndicator extends AbstractHealthIndicator {
NacosServiceMetaData nacosServiceMetaData = (NacosServiceMetaData) namingService; NacosServiceMetaData nacosServiceMetaData = (NacosServiceMetaData) namingService;
Properties properties = nacosServiceMetaData.getProperties(); Properties properties = nacosServiceMetaData.getProperties();
builder.withDetail( builder.withDetail(
JSON.toJSONString( JacksonUtils.toJson(
PropertiesUtils.extractSafeProperties(properties)), PropertiesUtils.extractSafeProperties(properties)),
namingService.getServerStatus()); namingService.getServerStatus());
} }
if (!namingService.getServerStatus().toLowerCase().equals(UP_STATUS)) { if (!namingService.getServerStatus().equalsIgnoreCase(UP_STATUS)) {
builder.down(); builder.down();
} }
} }

View File

@ -0,0 +1,2 @@
com.alibaba.boot.nacos.discovery.actuate.autoconfigure.NacosDiscoveryEndpointsAutoConfiguration
com.alibaba.boot.nacos.discovery.actuate.autoconfigure.NacosDiscoveryHealthIndicatorAutoConfiguration

View File

@ -0,0 +1,52 @@
/*
*
* * Licensed to the Apache Software Foundation (ASF) under one or more
* * contributor license agreements. See the NOTICE file distributed with
* * this work for additional information regarding copyright ownership.
* * The ASF licenses this file to You under the Apache License, Version 2.0
* * (the "License"); you may not use this file except in compliance with
* * the License. You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*/
package com.alibaba.boot.nacos.actuate.autoconfigure;
import com.alibaba.boot.nacos.discovery.actuate.autoconfigure.NacosDiscoveryEndpointsAutoConfiguration;
import com.alibaba.boot.nacos.discovery.actuate.endpoint.NacosDiscoveryEndpoint;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* {@link NacosDiscoveryEndpointsAutoConfiguration} Test
* @ClassName: NacosDiscoveryEndpointsAutoConfigurationTest
* @Author: SuperZ1999
* @Date: 2023/9/28
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {NacosDiscoveryEndpointsAutoConfiguration.class})
@TestPropertySource(properties = {
"management.endpoints.web.exposure.include=nacos-discovery"
})
public class NacosDiscoveryEndpointsAutoConfigurationTest {
@Autowired
private ApplicationContext context;
@Test
public void testNacosDiscoveryEndpointBean() {
Assert.assertNotNull(context.getBean(NacosDiscoveryEndpoint.class));
}
}

View File

@ -0,0 +1,48 @@
/*
*
* * Licensed to the Apache Software Foundation (ASF) under one or more
* * contributor license agreements. See the NOTICE file distributed with
* * this work for additional information regarding copyright ownership.
* * The ASF licenses this file to You under the Apache License, Version 2.0
* * (the "License"); you may not use this file except in compliance with
* * the License. You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*/
package com.alibaba.boot.nacos.actuate.autoconfigure;
import com.alibaba.boot.nacos.discovery.actuate.autoconfigure.NacosDiscoveryHealthIndicatorAutoConfiguration;
import com.alibaba.boot.nacos.discovery.actuate.health.NacosDiscoveryHealthIndicator;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* {@link NacosDiscoveryHealthIndicatorAutoConfiguration} Test
* @ClassName: NacosDiscoveryHealthIndicatorAutoConfigurationTest
* @Author: SuperZ1999
* @Date: 2023/9/28
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {NacosDiscoveryHealthIndicatorAutoConfiguration.class})
public class NacosDiscoveryHealthIndicatorAutoConfigurationTest {
@Autowired
private ApplicationContext context;
@Test
public void testNacosConfigHealthIndicatorBean() {
Assert.assertNotNull(context.getBean(NacosDiscoveryHealthIndicator.class));
}
}

View File

@ -21,14 +21,12 @@ import java.util.Map;
import com.alibaba.boot.nacos.discovery.actuate.endpoint.NacosDiscoveryEndpoint; import com.alibaba.boot.nacos.discovery.actuate.endpoint.NacosDiscoveryEndpoint;
import com.alibaba.boot.nacos.discovery.autoconfigure.NacosDiscoveryAutoConfiguration; import com.alibaba.boot.nacos.discovery.autoconfigure.NacosDiscoveryAutoConfiguration;
import com.alibaba.nacos.api.PropertyKeyConst;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
/** /**
@ -38,7 +36,6 @@ import org.springframework.test.context.junit4.SpringRunner;
* @see NacosDiscoveryEndpoint * @see NacosDiscoveryEndpoint
*/ */
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@TestPropertySource(properties = { "nacos.discovery.server-addr=localhost" })
@SpringBootTest(classes = { NacosDiscoveryEndpoint.class, @SpringBootTest(classes = { NacosDiscoveryEndpoint.class,
NacosDiscoveryAutoConfiguration.class }) NacosDiscoveryAutoConfiguration.class })
public class NacosDiscoveryEndpointTest { public class NacosDiscoveryEndpointTest {
@ -53,8 +50,7 @@ public class NacosDiscoveryEndpointTest {
HashMap nacosDiscoveryGlobalProperties = (HashMap) metadata HashMap nacosDiscoveryGlobalProperties = (HashMap) metadata
.get("nacosDiscoveryGlobalProperties"); .get("nacosDiscoveryGlobalProperties");
Assert.assertEquals("localhost", Assert.assertNotNull(nacosDiscoveryGlobalProperties);
nacosDiscoveryGlobalProperties.get(PropertyKeyConst.SERVER_ADDR));
} }
} }

View File

@ -0,0 +1 @@
nacos.discovery.serverAddr = "127.0.0.1:8848"

View File

@ -18,7 +18,7 @@
<parent> <parent>
<groupId>com.alibaba.boot</groupId> <groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-parent</artifactId> <artifactId>nacos-spring-boot-parent</artifactId>
<version>0.1.4</version> <version>${revision}</version>
<relativePath>../nacos-spring-boot-parent</relativePath> <relativePath>../nacos-spring-boot-parent</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -54,14 +54,33 @@
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId> <artifactId>nacos-spring-context</artifactId>
<optional>true</optional> <optional>true</optional>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${nacos.version}</version>
</dependency>
<dependency> <dependency>
<groupId>com.alibaba.boot</groupId> <groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-base</artifactId> <artifactId>nacos-spring-boot-base</artifactId>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-aot</artifactId>
<optional>true</optional>
</dependency>
<!-- Test Dependencies --> <!-- Test Dependencies -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>

View File

@ -25,9 +25,10 @@ import com.alibaba.nacos.spring.context.annotation.discovery.EnableNacosDiscover
*/ */
public interface NacosDiscoveryConstants { public interface NacosDiscoveryConstants {
String ENDPOINT_PREFIX = "nacos_discovery"; String PREFIX = "nacos.discovery";
String ENDPOINT_PREFIX = "nacos-discovery";
String ENABLED = EnableNacosDiscovery.DISCOVERY_PREFIX + "enabled"; String ENABLED = EnableNacosDiscovery.DISCOVERY_PREFIX + "enabled";
String PREFIX = "nacos.discovery";
} }

View File

@ -18,10 +18,14 @@ package com.alibaba.boot.nacos.discovery.autoconfigure;
/** /**
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a> * @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since 0.1.4 * @since 0.2.4
*/ */
public class AutoDeregisterException extends RuntimeException { public class AutoDeregisterException extends RuntimeException {
public AutoDeregisterException(String message) {
super(message);
}
public AutoDeregisterException(Throwable cause) { public AutoDeregisterException(Throwable cause) {
super(cause); super(cause);
} }

View File

@ -18,10 +18,14 @@ package com.alibaba.boot.nacos.discovery.autoconfigure;
/** /**
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a> * @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since 0.1.3 * @since 0.2.3
*/ */
public class AutoRegisterException extends RuntimeException { public class AutoRegisterException extends RuntimeException {
public AutoRegisterException(String message) {
super(message);
}
public AutoRegisterException(Throwable cause) { public AutoRegisterException(Throwable cause) {
super(cause); super(cause);
} }

View File

@ -16,6 +16,7 @@
*/ */
package com.alibaba.boot.nacos.discovery.autoconfigure; package com.alibaba.boot.nacos.discovery.autoconfigure;
import com.alibaba.boot.nacos.aot.context.EnableNacosDiscoveryAotProcessor;
import com.alibaba.boot.nacos.discovery.NacosDiscoveryConstants; import com.alibaba.boot.nacos.discovery.NacosDiscoveryConstants;
import com.alibaba.boot.nacos.discovery.properties.NacosDiscoveryProperties; import com.alibaba.boot.nacos.discovery.properties.NacosDiscoveryProperties;
import com.alibaba.nacos.spring.context.annotation.discovery.EnableNacosDiscovery; import com.alibaba.nacos.spring.context.annotation.discovery.EnableNacosDiscovery;
@ -26,6 +27,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import static com.alibaba.nacos.spring.util.NacosBeanUtils.DISCOVERY_GLOBAL_NACOS_PROPERTIES_BEAN_NAME; import static com.alibaba.nacos.spring.util.NacosBeanUtils.DISCOVERY_GLOBAL_NACOS_PROPERTIES_BEAN_NAME;
@ -38,7 +40,8 @@ import static com.alibaba.nacos.spring.util.NacosBeanUtils.DISCOVERY_GLOBAL_NACO
@ConditionalOnMissingBean(name = DISCOVERY_GLOBAL_NACOS_PROPERTIES_BEAN_NAME) @ConditionalOnMissingBean(name = DISCOVERY_GLOBAL_NACOS_PROPERTIES_BEAN_NAME)
@EnableNacosDiscovery @EnableNacosDiscovery
@EnableConfigurationProperties(value = NacosDiscoveryProperties.class) @EnableConfigurationProperties(value = NacosDiscoveryProperties.class)
@ConditionalOnClass(name = "org.springframework.boot.bind.RelaxedDataBinder") @ConditionalOnClass(name = "org.springframework.boot.context.properties.bind.Binder")
@Import(EnableNacosDiscoveryAotProcessor.class)
public class NacosDiscoveryAutoConfiguration { public class NacosDiscoveryAutoConfiguration {
@Bean @Bean

View File

@ -21,20 +21,20 @@ import com.alibaba.boot.nacos.discovery.properties.Register;
import com.alibaba.nacos.api.annotation.NacosInjected; import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService; import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.client.naming.utils.NetUtils; import com.alibaba.nacos.api.utils.NetUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.embedded.EmbeddedServletContainer; import org.springframework.boot.web.server.WebServer;
import org.springframework.context.ApplicationListener; import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent; import org.springframework.context.event.ContextClosedEvent;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a> * @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since 0.1.4 * @since 0.2.4
*/ */
@Component @Component
public class NacosDiscoveryAutoDeregister public class NacosDiscoveryAutoDeregister
@ -47,13 +47,13 @@ public class NacosDiscoveryAutoDeregister
private NamingService namingService; private NamingService namingService;
private final NacosDiscoveryProperties discoveryProperties; private final NacosDiscoveryProperties discoveryProperties;
private final EmbeddedServletContainer webServer; private final WebServer webServer;
@Value("${spring.application.name:spring.application.name}") @Value("${spring.application.name:}")
private String applicationName; private String applicationName;
public NacosDiscoveryAutoDeregister(NacosDiscoveryProperties discoveryProperties, public NacosDiscoveryAutoDeregister(NacosDiscoveryProperties discoveryProperties,
EmbeddedServletContainer webServer) { WebServer webServer) {
this.discoveryProperties = discoveryProperties; this.discoveryProperties = discoveryProperties;
this.webServer = webServer; this.webServer = webServer;
} }
@ -74,15 +74,20 @@ public class NacosDiscoveryAutoDeregister
register.setPort(webServer.getPort()); register.setPort(webServer.getPort());
} }
String serviceName = StringUtils.isEmpty(register.getServiceName()) String serviceName = register.getServiceName();
? applicationName
: register.getServiceName(); if (StringUtils.isEmpty(serviceName)){
if (StringUtils.isEmpty(applicationName)){
throw new AutoDeregisterException("serviceName notNull");
}
serviceName = applicationName;
}
try { try {
namingService.deregisterInstance(serviceName, register.getGroupName(), namingService.deregisterInstance(serviceName, register.getGroupName(),
register); register);
logger.info("Finished auto deregister service : {}, ip : {}, port : {}", logger.info("Finished auto deregister service : {}, ip : {}, port : {}",
register.getServiceName(), register.getIp(), register.getPort()); serviceName, register.getIp(), register.getPort());
} }
catch (NacosException e) { catch (NacosException e) {
throw new AutoDeregisterException(e); throw new AutoDeregisterException(e);

View File

@ -21,24 +21,25 @@ import com.alibaba.boot.nacos.discovery.properties.Register;
import com.alibaba.nacos.api.annotation.NacosInjected; import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService; import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.client.naming.utils.NetUtils; import com.alibaba.nacos.api.utils.NetUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent; import org.springframework.boot.web.context.WebServerInitializedEvent;
import org.springframework.context.ApplicationListener; import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a> * @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since 0.1.3 * @since 0.2.3
*/ */
@Component @Component
public class NacosDiscoveryAutoRegister public class NacosDiscoveryAutoRegister
implements ApplicationListener<EmbeddedServletContainerInitializedEvent> { implements ApplicationListener<WebServerInitializedEvent> {
private static final Logger logger = LoggerFactory private static final Logger logger = LoggerFactory
.getLogger(NacosDiscoveryAutoRegister.class); .getLogger(NacosDiscoveryAutoRegister.class);
@ -49,11 +50,11 @@ public class NacosDiscoveryAutoRegister
@Autowired @Autowired
private NacosDiscoveryProperties discoveryProperties; private NacosDiscoveryProperties discoveryProperties;
@Value("${spring.application.name:spring.application.name}") @Value("${spring.application.name:}")
private String application; private String applicationName;
@Override @Override
public void onApplicationEvent(EmbeddedServletContainerInitializedEvent event) { public void onApplicationEvent(WebServerInitializedEvent event) {
if (!discoveryProperties.isAutoRegister()) { if (!discoveryProperties.isAutoRegister()) {
return; return;
@ -66,23 +67,29 @@ public class NacosDiscoveryAutoRegister
} }
if (register.getPort() == 0) { if (register.getPort() == 0) {
register.setPort(event.getSource().getPort()); register.setPort(event.getWebServer().getPort());
} }
register.getMetadata().put("preserved.register.source", "SPRING_BOOT"); register.getMetadata().put("preserved.register.source", "SPRING_BOOT");
register.setInstanceId(""); register.setInstanceId("");
String serviceName = StringUtils.isEmpty(register.getServiceName()) ? application
: register.getServiceName(); String serviceName = register.getServiceName();
if (StringUtils.isEmpty(serviceName)){
if (StringUtils.isEmpty(applicationName)){
throw new AutoRegisterException("serviceName notNull");
}
serviceName = applicationName;
}
try { try {
namingService.registerInstance(serviceName, register.getGroupName(), namingService.registerInstance(serviceName, register.getGroupName(),
register); register);
logger.info("Finished auto register service : {}, ip : {}, port : {}", logger.info("Finished auto register service : {}, ip : {}, port : {}",
register.getServiceName(), register.getIp(), register.getPort()); serviceName, register.getIp(), register.getPort());
} } catch (NacosException e) {
catch (NacosException e) { throw new AutoRegisterException(e);
throw new RuntimeException(e);
} }
} }

View File

@ -49,6 +49,26 @@ public class NacosDiscoveryProperties {
@NestedConfigurationProperty @NestedConfigurationProperty
private Register register = new Register(); private Register register = new Register();
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getServerAddr() { public String getServerAddr() {
return serverAddr; return serverAddr;
} }

View File

@ -21,7 +21,7 @@ import com.alibaba.nacos.api.naming.pojo.Instance;
/** /**
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a> * @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since 0.1.3 * @since 0.2.3
*/ */
public class Register extends Instance { public class Register extends Instance {

View File

@ -1,66 +0,0 @@
{
"hints": [ ],
"groups": [ ],
"properties": [
{
"sourceType": "com.alibaba.boot.nacos.discovery.properties.NacosDiscoveryProperties",
"name": "nacos.discovery.enabled",
"description": "enable or disable nacos discovery feature",
"type": "java.lang.Boolean"
},
{
"sourceType": "com.alibaba.boot.nacos.discovery.properties.NacosDiscoveryProperties",
"name": "nacos.discovery.server-addr",
"description": "the server address of nacos",
"type": "java.lang.String"
},
{
"sourceType": "com.alibaba.boot.nacos.discovery.properties.NacosDiscoveryProperties",
"name": "nacos.discovery.context-path",
"description": "the context path of nacos server",
"type": "java.lang.String"
},
{
"sourceType": "com.alibaba.boot.nacos.discovery.properties.NacosDiscoveryProperties",
"name": "nacos.discovery.endpoint",
"description": "the entry domain name of a service in each region",
"type": "java.lang.String"
},
{
"sourceType": "com.alibaba.boot.nacos.discovery.properties.NacosDiscoveryProperties",
"name": "nacos.discovery.cluster-name",
"description": "cluster info under service",
"type": "java.lang.String"
},
{
"sourceType": "com.alibaba.boot.nacos.discovery.properties.NacosDiscoveryProperties",
"name": "nacos.discovery.namespace",
"description": "for configuration isolation by tenants. Different namespaces may have configurations with the same Group or Data ID. ",
"type": "java.lang.String"
},
{
"sourceType": "com.alibaba.boot.nacos.discovery.properties.NacosDiscoveryProperties",
"name": "nacos.discovery.access-key",
"description": "the accesskey of Alibaba Cloud Account",
"type": "java.lang.String"
},
{
"sourceType": "com.alibaba.boot.nacos.discovery.properties.NacosDiscoveryProperties",
"name": "nacos.discovery.secret-key",
"description": "the secretkey of Alibaba Cloud Account",
"type": "java.lang.String"
},
{
"sourceType": "com.alibaba.boot.nacos.discovery.properties.NacosDiscoveryProperties",
"name": "nacos.discovery.register",
"description": "the service",
"type": "com.alibaba.boot.nacos.discovery.properties.Register"
},
{
"sourceType": "com.alibaba.boot.nacos.discovery.properties.NacosDiscoveryProperties",
"name": "nacos.discovery.auto-register",
"description": "the service",
"type": "java.lang.Boolean"
}
]
}

View File

@ -0,0 +1 @@
com.alibaba.boot.nacos.discovery.autoconfigure.NacosDiscoveryAutoConfiguration

View File

@ -19,6 +19,7 @@ package com.alibaba.boot.nacos.autoconfigure;
import java.util.Properties; import java.util.Properties;
import com.alibaba.boot.nacos.discovery.autoconfigure.NacosDiscoveryAutoConfiguration; import com.alibaba.boot.nacos.discovery.autoconfigure.NacosDiscoveryAutoConfiguration;
import com.alibaba.boot.nacos.discovery.autoconfigure.NacosDiscoveryAutoRegister;
import com.alibaba.boot.nacos.discovery.properties.NacosDiscoveryProperties; import com.alibaba.boot.nacos.discovery.properties.NacosDiscoveryProperties;
import com.alibaba.nacos.api.PropertyKeyConst; import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.annotation.NacosInjected; import com.alibaba.nacos.api.annotation.NacosInjected;
@ -64,13 +65,13 @@ public class NacosDiscoveryAutoConfigurationTest {
} }
@Test(expected = NoSuchBeanDefinitionException.class) @Test(expected = NoSuchBeanDefinitionException.class)
public void testNacosConfigGlobalBean() { public void testNacosDiscoveryGlobalBean() {
Assert.assertNull(applicationContext Assert.assertNull(applicationContext
.getBean(NacosBeanUtils.GLOBAL_NACOS_PROPERTIES_BEAN_NAME)); .getBean(NacosBeanUtils.GLOBAL_NACOS_PROPERTIES_BEAN_NAME));
} }
@Test(expected = NoSuchBeanDefinitionException.class) @Test(expected = NoSuchBeanDefinitionException.class)
public void testNacosDiscoveryGlobalBean() { public void testNacosConfigGlobalBean() {
Assert.assertNull(applicationContext Assert.assertNull(applicationContext
.getBean(NacosBeanUtils.CONFIG_GLOBAL_NACOS_PROPERTIES_BEAN_NAME)); .getBean(NacosBeanUtils.CONFIG_GLOBAL_NACOS_PROPERTIES_BEAN_NAME));
} }
@ -84,4 +85,8 @@ public class NacosDiscoveryAutoConfigurationTest {
properties.getProperty(PropertyKeyConst.SERVER_ADDR)); properties.getProperty(PropertyKeyConst.SERVER_ADDR));
} }
@Test
public void testAddNacosDiscoveryAutoRegister() {
Assert.assertNotNull(applicationContext.getBean(NacosDiscoveryAutoRegister.class));
}
} }

View File

@ -18,7 +18,7 @@
<parent> <parent>
<groupId>com.alibaba.boot</groupId> <groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-parent</artifactId> <artifactId>nacos-spring-boot-parent</artifactId>
<version>0.1.4</version> <version>${revision}</version>
<relativePath>../nacos-spring-boot-parent</relativePath> <relativePath>../nacos-spring-boot-parent</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -34,13 +34,24 @@
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId> <artifactId>spring-boot-starter</artifactId>
<scope>true</scope>
</dependency> </dependency>
<!-- Nacos --> <!-- Nacos -->
<dependency> <dependency>
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId> <artifactId>nacos-spring-context</artifactId>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${nacos.version}</version>
</dependency> </dependency>
<dependency> <dependency>
@ -53,5 +64,10 @@
<artifactId>nacos-spring-boot-base</artifactId> <artifactId>nacos-spring-boot-base</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-aot</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ /*
~ * Licensed to the Apache Software Foundation (ASF) under one or more
~ * contributor license agreements. See the NOTICE file distributed with
~ * this work for additional information regarding copyright ownership.
~ * The ASF licenses this file to You under the Apache License, Version 2.0
~ * (the "License"); you may not use this file except in compliance with
~ * the License. You may obtain a copy of the License at
~ *
~ * http://www.apache.org/licenses/LICENSE-2.0
~ *
~ * Unless required by applicable law or agreed to in writing, software
~ * distributed under the License is distributed on an "AS IS" BASIS,
~ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ * See the License for the specific language governing permissions and
~ * limitations under the License.
~ */
-->
<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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-parent</artifactId>
<version>${revision}</version>
<relativePath>../nacos-spring-boot-parent</relativePath>
</parent>
<artifactId>nacos-spring-boot-aot</artifactId>
<packaging>jar</packaging>
<name>Nacos Spring Boot Aot</name>
<description>Nacos Spring Boot Aot</description>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring6.framework.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring6.framework.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring6.framework.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId>
<version>${nacos-spring-context.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${nacos.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,105 @@
/*
*
* * Licensed to the Apache Software Foundation (ASF) under one or more
* * contributor license agreements. See the NOTICE file distributed with
* * this work for additional information regarding copyright ownership.
* * The ASF licenses this file to You under the Apache License, Version 2.0
* * (the "License"); you may not use this file except in compliance with
* * the License. You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*/
package com.alibaba.boot.nacos.aot.context;
import com.alibaba.boot.nacos.aot.util.AotDetector;
import com.alibaba.nacos.spring.context.annotation.config.EnableNacosConfig;
import com.alibaba.nacos.spring.context.annotation.config.NacosConfigBeanDefinitionRegistrar;
import com.alibaba.nacos.spring.core.env.NacosPropertySourcePostProcessor;
import com.alibaba.nacos.spring.util.NacosBeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;
import java.util.Map;
import static com.alibaba.nacos.spring.util.NacosBeanUtils.*;
/**
* {@link EnableNacosConfig} AotProcessor
* Except for the operation of registering BeanDefinition, all other operations in {@link NacosConfigBeanDefinitionRegistrar} must be done here
* because spring will not call {@link NacosConfigBeanDefinitionRegistrar#registerBeanDefinitions} in AOT.
* @author SuperZ1999
*/
public class EnableNacosConfigAotProcessor implements BeanDefinitionRegistryPostProcessor, EnvironmentAware, BeanFactoryAware {
private Environment environment;
private BeanFactory beanFactory;
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
if (!AotDetector.useGeneratedArtifacts()) {
return;
}
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) this.beanFactory;
Map<String, Object> beansWithAnnotation = beanFactory.getBeansWithAnnotation(EnableNacosConfig.class);
Object[] beans = beansWithAnnotation.values().toArray();
if (beans.length != 0) {
// only handle the first one
Class<?> aClass = beans[0].getClass();
if (aClass.getAnnotation(EnableNacosConfig.class) == null) {
// cglib proxy object
aClass = aClass.getSuperclass();
}
AnnotationMetadata annotationMetadata = AnnotationMetadata.introspect(aClass);
AnnotationAttributes attributes = AnnotationAttributes
.fromMap(annotationMetadata
.getAnnotationAttributes(EnableNacosConfig.class.getName()));
// Register Global Nacos Properties Bean
registerGlobalNacosProperties(attributes, registry, environment,
CONFIG_GLOBAL_NACOS_PROPERTIES_BEAN_NAME);
}
registerNacosConfigListenerExecutor(registry, environment);
// replace NacosPropertySourcePostProcessor with NacosPropertySourcePostProcessorForAot
if (registry.containsBeanDefinition(NacosPropertySourcePostProcessor.BEAN_NAME)) {
registry.removeBeanDefinition(NacosPropertySourcePostProcessor.BEAN_NAME);
}
NacosBeanUtils.registerInfrastructureBeanIfAbsent(registry, NacosPropertySourcePostProcessorForAot.BEAN_NAME,
NacosPropertySourcePostProcessorForAot.class);
// Invoke NacosPropertySourcePostProcessor immediately
// in order to enhance the precedence of @NacosPropertySource process
invokeNacosPropertySourcePostProcessor(this.beanFactory);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
}

View File

@ -0,0 +1,94 @@
/*
*
* * Licensed to the Apache Software Foundation (ASF) under one or more
* * contributor license agreements. See the NOTICE file distributed with
* * this work for additional information regarding copyright ownership.
* * The ASF licenses this file to You under the Apache License, Version 2.0
* * (the "License"); you may not use this file except in compliance with
* * the License. You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*/
package com.alibaba.boot.nacos.aot.context;
import com.alibaba.boot.nacos.aot.util.AotDetector;
import com.alibaba.nacos.spring.context.annotation.discovery.EnableNacosDiscovery;
import com.alibaba.nacos.spring.context.annotation.discovery.NacosDiscoveryBeanDefinitionRegistrar;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;
import java.util.Map;
import static com.alibaba.nacos.spring.util.NacosBeanUtils.*;
/**
* {@link EnableNacosDiscovery} AotProcessor
* Except for the operation of registering BeanDefinition, all other operations in {@link NacosDiscoveryBeanDefinitionRegistrar} must be done here
* because spring will not call {@link NacosDiscoveryBeanDefinitionRegistrar#registerBeanDefinitions} in AOT.
* @author SuperZ1999
*/
public class EnableNacosDiscoveryAotProcessor implements BeanDefinitionRegistryPostProcessor, EnvironmentAware, BeanFactoryAware {
private Environment environment;
private BeanFactory beanFactory;
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
if (!AotDetector.useGeneratedArtifacts()) {
return;
}
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) this.beanFactory;
Map<String, Object> beansWithAnnotation = beanFactory.getBeansWithAnnotation(EnableNacosDiscovery.class);
Object[] beans = beansWithAnnotation.values().toArray();
if (beans.length != 0) {
// only handle the first one
Class<?> aClass = beans[0].getClass();
if (aClass.getAnnotation(EnableNacosDiscovery.class) == null) {
// cglib proxy object
aClass = aClass.getSuperclass();
}
AnnotationMetadata annotationMetadata = AnnotationMetadata.introspect(aClass);
AnnotationAttributes attributes = AnnotationAttributes
.fromMap(annotationMetadata
.getAnnotationAttributes(EnableNacosDiscovery.class.getName()));
// Register Global Nacos Properties Bean
registerGlobalNacosProperties(attributes, registry, environment,
DISCOVERY_GLOBAL_NACOS_PROPERTIES_BEAN_NAME);
registerGlobalNacosProperties(attributes, registry, environment,
MAINTAIN_GLOBAL_NACOS_PROPERTIES_BEAN_NAME);
}
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
}

View File

@ -0,0 +1,90 @@
/*
*
* * Licensed to the Apache Software Foundation (ASF) under one or more
* * contributor license agreements. See the NOTICE file distributed with
* * this work for additional information regarding copyright ownership.
* * The ASF licenses this file to You under the Apache License, Version 2.0
* * (the "License"); you may not use this file except in compliance with
* * the License. You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*/
package com.alibaba.boot.nacos.aot.context;
import com.alibaba.boot.nacos.aot.util.AotDetector;
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
import com.alibaba.nacos.spring.core.env.AbstractNacosPropertySourceBuilder;
import com.alibaba.nacos.spring.core.env.NacosPropertySourcePostProcessor;
import com.alibaba.spring.util.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import java.util.ArrayList;
import java.util.Map;
import static com.alibaba.nacos.spring.util.NacosBeanUtils.getConfigServiceBeanBuilder;
public class NacosPropertySourcePostProcessorForAot extends NacosPropertySourcePostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
String[] abstractNacosPropertySourceBuilderBeanNames = BeanUtils
.getBeanNames(beanFactory, AbstractNacosPropertySourceBuilder.class);
this.nacosPropertySourceBuilders = new ArrayList<AbstractNacosPropertySourceBuilder>(
abstractNacosPropertySourceBuilderBeanNames.length);
for (String beanName : abstractNacosPropertySourceBuilderBeanNames) {
this.nacosPropertySourceBuilders.add(beanFactory.getBean(beanName,
AbstractNacosPropertySourceBuilder.class));
}
NacosPropertySourcePostProcessor.beanFactory = beanFactory;
this.configServiceBeanBuilder = getConfigServiceBeanBuilder(beanFactory);
if (AotDetector.useGeneratedArtifacts()) {
// the type of all BeanDefinitions is RootBeanDefinition in AOT, but what we need is AnnotatedGenericBeanDefinition.
Map<String, Object> beansWithAnnotation = beanFactory.getBeansWithAnnotation(NacosPropertySource.class);
for (Map.Entry<String, Object> entry : beansWithAnnotation.entrySet()) {
processPropertySourceForAot(entry.getKey(), entry.getValue());
}
}
String[] beanNames = beanFactory.getBeanDefinitionNames();
for (String beanName : beanNames) {
processPropertySource(beanName, beanFactory);
}
}
private void processPropertySourceForAot(String beanName, Object bean) {
if (processedBeanNames.contains(beanName)) {
return;
}
BeanDefinition beanDefinition = null;
Class<?> aClass = bean.getClass();
NacosPropertySource[] annotations = aClass.getSuperclass().getAnnotationsByType(NacosPropertySource.class);
if (annotations.length != 0) {
beanDefinition = new AnnotatedGenericBeanDefinition(aClass.getSuperclass());
}
annotations = aClass.getAnnotationsByType(NacosPropertySource.class);
if (annotations.length != 0) {
beanDefinition = new AnnotatedGenericBeanDefinition(aClass);
}
doProcessPropertySource(beanName, beanDefinition);
processedBeanNames.add(beanName);
}
}

View File

@ -0,0 +1,76 @@
/*
*
* * Licensed to the Apache Software Foundation (ASF) under one or more
* * contributor license agreements. See the NOTICE file distributed with
* * this work for additional information regarding copyright ownership.
* * The ASF licenses this file to You under the Apache License, Version 2.0
* * (the "License"); you may not use this file except in compliance with
* * the License. You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*/
package com.alibaba.boot.nacos.aot.hint;
import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import org.springframework.aot.generate.GenerationContext;
import org.springframework.beans.factory.aot.BeanRegistrationAotContribution;
import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor;
import org.springframework.beans.factory.aot.BeanRegistrationCode;
import org.springframework.beans.factory.support.RegisteredBean;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
/**
* {@link NacosInjected} and {@link NacosValue} AotProcessor
* The fields annotated with {@link NacosInjected} or {@link NacosValue} must be added to the reflect-config.json
* @author SuperZ1999
*/
public class NacosAnnotationBeanRegistrationAotProcessor implements BeanRegistrationAotProcessor {
@Override
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
Class<?> beanClass = registeredBean.getBeanClass();
List<Field> fields = new ArrayList<>();
ReflectionUtils.doWithFields(beanClass, field -> {
NacosInjected injectedAnnotation = field.getDeclaredAnnotation(NacosInjected.class);
NacosValue nacosValueAnnotation = field.getDeclaredAnnotation(NacosValue.class);
if (injectedAnnotation != null || nacosValueAnnotation != null) {
fields.add(field);
}
});
if (fields.isEmpty()) {
return null;
}
return new AotContribution(fields);
}
private static class AotContribution implements BeanRegistrationAotContribution {
private final List<Field> fields;
public AotContribution() {
this.fields = new ArrayList<>();
}
public AotContribution(List<Field> fields) {
this.fields = fields;
}
@Override
public void applyTo(GenerationContext generationContext, BeanRegistrationCode beanRegistrationCode) {
for (Field field : fields) {
generationContext.getRuntimeHints().reflection().registerField(field);
}
}
}
}

View File

@ -0,0 +1,45 @@
/*
*
* * Licensed to the Apache Software Foundation (ASF) under one or more
* * contributor license agreements. See the NOTICE file distributed with
* * this work for additional information regarding copyright ownership.
* * The ASF licenses this file to You under the Apache License, Version 2.0
* * (the "License"); you may not use this file except in compliance with
* * the License. You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*/
package com.alibaba.boot.nacos.aot.util;
import org.springframework.core.NativeDetector;
import org.springframework.core.SpringProperties;
public abstract class AotDetector {
/**
* System property that indicates the application should run with AOT
* generated artifacts. If such optimizations are not available, it is
* recommended to throw an exception rather than fall back to the regular
* runtime behavior.
*/
public static final String AOT_ENABLED = "spring.aot.enabled";
/**
* Determine whether AOT optimizations must be considered at runtime. This
* is mandatory in a native image but can be triggered on the JVM using
* the {@value #AOT_ENABLED} Spring property.
* @return whether AOT optimizations must be considered
*/
public static boolean useGeneratedArtifacts() {
return (NativeDetector.inNativeImage() || SpringProperties.getFlag(AOT_ENABLED));
}
}

View File

@ -0,0 +1,33 @@
/*
*
* * Licensed to the Apache Software Foundation (ASF) under one or more
* * contributor license agreements. See the NOTICE file distributed with
* * this work for additional information regarding copyright ownership.
* * The ASF licenses this file to You under the Apache License, Version 2.0
* * (the "License"); you may not use this file except in compliance with
* * the License. You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*/
package com.alibaba.boot.nacos.aot.util;
public abstract class NativeDetector {
// See https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java
private static final boolean imageCode = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);
/**
* Returns {@code true} if invoked in the context of image building or during image runtime, else {@code false}.
*/
public static boolean inNativeImage() {
return imageCode;
}
}

View File

@ -0,0 +1,9 @@
[
{
"name": "com.alibaba.boot.nacos.aot.context.NacosPropertySourcePostProcessorForAot",
"allDeclaredClasses": true,
"allDeclaredMethods": true,
"allDeclaredFields": true,
"allDeclaredConstructors": true
}
]

View File

@ -0,0 +1,15 @@
{
"resources": {
"includes": [
{
"pattern": "\\QMETA-INF/spring.handlers\\E"
},
{
"pattern": "\\QMETA-INF/spring.schemas\\E"
},
{
"pattern": "\\QMETA-INF/schemas/nacos.xsd\\E"
}
]
}
}

View File

@ -0,0 +1,2 @@
org.springframework.beans.factory.aot.BeanRegistrationAotProcessor=\
com.alibaba.boot.nacos.aot.hint.NacosAnnotationBeanRegistrationAotProcessor

View File

@ -18,7 +18,7 @@
<parent> <parent>
<groupId>com.alibaba.boot</groupId> <groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-parent</artifactId> <artifactId>nacos-spring-boot-parent</artifactId>
<version>0.1.4</version> <version>${revision}</version>
<relativePath>../nacos-spring-boot-parent</relativePath> <relativePath>../nacos-spring-boot-parent</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -54,8 +54,21 @@
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId> <artifactId>nacos-spring-context</artifactId>
<optional>true</optional> <optional>true</optional>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${nacos.version}</version>
</dependency>
<!-- Test Dependencies --> <!-- Test Dependencies -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>

View File

@ -16,7 +16,6 @@
package com.alibaba.boot.nacos.common; package com.alibaba.boot.nacos.common;
import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
@ -30,13 +29,11 @@ public class PropertiesUtils {
public static Map<Object, Object> extractSafeProperties(Properties properties) { public static Map<Object, Object> extractSafeProperties(Properties properties) {
Map<Object, Object> result = new HashMap<>(); Map<Object, Object> result = new HashMap<>();
Enumeration enumeration = properties.propertyNames(); properties.forEach((key, val) -> {
while (enumeration.hasMoreElements()) {
String key = enumeration.nextElement().toString();
if (!PropertyKeyConst.SECRET_KEY.equals(key)) { if (!PropertyKeyConst.SECRET_KEY.equals(key)) {
result.put(key, properties.get(key)); result.put(key, val);
}
} }
});
return result; return result;
} }

View File

@ -0,0 +1 @@
com.alibaba.boot.nacos.common.NacosFailureAnalyzer

View File

@ -18,7 +18,7 @@
<parent> <parent>
<groupId>com.alibaba.boot</groupId> <groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-project</artifactId> <artifactId>nacos-spring-boot-project</artifactId>
<version>0.1.4</version> <version>${revision}</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
@ -30,14 +30,14 @@
<description>Nacos Spring Boot Parent</description> <description>Nacos Spring Boot Parent</description>
<properties> <properties>
<java.version>1.7</java.version> <java.version>1.8</java.version>
<java.source.version>1.7</java.source.version> <java.source.version>1.8</java.source.version>
<java.target.version>1.7</java.target.version> <java.target.version>1.8</java.target.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>1.4.1.RELEASE</spring-boot.version> <spring-boot.version>2.6.3</spring-boot.version>
<nacos.version>0.1.0</nacos.version> <spring6.framework.version>6.0.8</spring6.framework.version>
<nacos-spring-context.version>0.3.4</nacos-spring-context.version> <nacos-spring-context.version>2.1.0-RC</nacos-spring-context.version>
<!-- Build args --> <!-- Build args -->
<argline>-server -Xms256m -Xmx512m -XX:PermSize=64m -XX:MaxPermSize=128m -Dfile.encoding=UTF-8 <argline>-server -Xms256m -Xmx512m -XX:PermSize=64m -XX:MaxPermSize=128m -Dfile.encoding=UTF-8
-Djava.net.preferIPv4Stack=true -Djava.net.preferIPv4Stack=true
@ -53,23 +53,12 @@
<maven-release-plugin.version>2.5.3</maven-release-plugin.version> <maven-release-plugin.version>2.5.3</maven-release-plugin.version>
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version> <maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
<maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version> <maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
<nacos.version>2.2.1</nacos.version>
</properties> </properties>
<dependencyManagement> <dependencyManagement>
<dependencies> <dependencies>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
</dependency>
<!-- Spring Boot --> <!-- Spring Boot -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
@ -84,6 +73,18 @@
<groupId>com.alibaba.nacos</groupId> <groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId> <artifactId>nacos-spring-context</artifactId>
<version>${nacos-spring-context.version}</version> <version>${nacos-spring-context.version}</version>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${nacos.version}</version>
</dependency> </dependency>
<dependency> <dependency>
@ -92,6 +93,12 @@
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-aot</artifactId>
<version>${project.version}</version>
</dependency>
<dependency> <dependency>
<groupId>com.alibaba.boot</groupId> <groupId>com.alibaba.boot</groupId>
<artifactId>nacos-config-spring-boot-autoconfigure</artifactId> <artifactId>nacos-config-spring-boot-autoconfigure</artifactId>
@ -169,6 +176,16 @@
</pluginRepository> </pluginRepository>
</pluginRepositories> </pluginRepositories>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
</dependencies>
<build> <build>
<!-- Used for packaging NOTICE & LICENSE to each sub-module jar--> <!-- Used for packaging NOTICE & LICENSE to each sub-module jar-->
<resources> <resources>
@ -265,7 +282,7 @@
<configuration> <configuration>
<rules> <rules>
<requireJavaVersion> <requireJavaVersion>
<version>[1.7,)</version> <version>[1.8,)</version>
</requireJavaVersion> </requireJavaVersion>
<requireProperty> <requireProperty>
<property>project.name</property> <property>project.name</property>

View File

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ /*
~ * Licensed to the Apache Software Foundation (ASF) under one or more
~ * contributor license agreements. See the NOTICE file distributed with
~ * this work for additional information regarding copyright ownership.
~ * The ASF licenses this file to You under the Apache License, Version 2.0
~ * (the "License"); you may not use this file except in compliance with
~ * the License. You may obtain a copy of the License at
~ *
~ * http://www.apache.org/licenses/LICENSE-2.0
~ *
~ * Unless required by applicable law or agreed to in writing, software
~ * distributed under the License is distributed on an "AS IS" BASIS,
~ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ * See the License for the specific language governing permissions and
~ * limitations under the License.
~ */
-->
<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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-samples</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>nacos-aot-sample</artifactId>
<packaging>jar</packaging>
<name>Nacos Spring Boot Aot Sample</name>
<description>Nacos Spring Boot Aot Sample</description>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.0.6</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-config-spring-boot-starter</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-discovery-spring-boot-starter</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<profiles>
<profile>
<id>native</id>
<build>
<plugins>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>0.9.25</version>
<executions>
<execution>
<id>compile</id>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
<configuration>
<classesDirectory>${project.build.outputDirectory}</classesDirectory>
<mainClass>com.alibaba.boot.nacos.sample.AotApplication</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>process-aot</id>
<goals>
<goal>process-aot</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,32 @@
/*
*
* * Licensed to the Apache Software Foundation (ASF) under one or more
* * contributor license agreements. See the NOTICE file distributed with
* * this work for additional information regarding copyright ownership.
* * The ASF licenses this file to You under the Apache License, Version 2.0
* * (the "License"); you may not use this file except in compliance with
* * the License. You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*/
package com.alibaba.boot.nacos.sample;
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@NacosPropertySource(dataId = "example", autoRefreshed = true)
public class AotApplication {
public static void main(String[] args) {
SpringApplication.run(AotApplication.class, args);
}
}

View File

@ -0,0 +1,65 @@
/*
*
* * Licensed to the Apache Software Foundation (ASF) under one or more
* * contributor license agreements. See the NOTICE file distributed with
* * this work for additional information regarding copyright ownership.
* * The ASF licenses this file to You under the Apache License, Version 2.0
* * (the "License"); you may not use this file except in compliance with
* * the License. You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*/
package com.alibaba.boot.nacos.sample.controller;
import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
import static org.springframework.web.bind.annotation.RequestMethod.GET;
@Controller
public class AotController {
@NacosInjected
private ConfigService configService;
@NacosInjected
private NamingService namingService;
@NacosValue(value = "${flag:false}", autoRefreshed = true)
private boolean flag;
@ResponseBody
@RequestMapping(value = "/config/get", method = GET)
public String getConfig() throws NacosException {
return configService.getConfig("example", "DEFAULT_GROUP", 5000);
}
@ResponseBody
@RequestMapping(value = "/naming/get", method = GET)
public List<Instance> getNaming(@RequestParam("serviceName") String serviceName) throws NacosException {
return namingService.getAllInstances(serviceName);
}
@ResponseBody
@RequestMapping(value = "/flag/get", method = GET)
public boolean getFlag() {
return flag;
}
}

View File

@ -0,0 +1,36 @@
[
{
"name":"[Lcom.sun.management.internal.DiagnosticCommandArgumentInfo;"
},
{
"name":"[Lcom.sun.management.internal.DiagnosticCommandInfo;"
},
{
"name":"com.sun.management.internal.DiagnosticCommandArgumentInfo",
"methods":[{"name":"<init>","parameterTypes":["java.lang.String","java.lang.String","java.lang.String","java.lang.String","boolean","boolean","boolean","int"] }]
},
{
"name":"com.sun.management.internal.DiagnosticCommandInfo",
"methods":[{"name":"<init>","parameterTypes":["java.lang.String","java.lang.String","java.lang.String","java.lang.String","java.lang.String","java.lang.String","boolean","java.util.List"] }]
},
{
"name":"java.lang.Boolean",
"methods":[{"name":"getBoolean","parameterTypes":["java.lang.String"] }]
},
{
"name":"java.lang.InternalError",
"methods":[{"name":"<init>","parameterTypes":["java.lang.String"] }]
},
{
"name":"java.util.Arrays",
"methods":[{"name":"asList","parameterTypes":["java.lang.Object[]"] }]
},
{
"name":"sun.instrument.InstrumentationImpl",
"methods":[{"name":"<init>","parameterTypes":["long","boolean","boolean"] }, {"name":"loadClassAndCallAgentmain","parameterTypes":["java.lang.String","java.lang.String"] }, {"name":"loadClassAndCallPremain","parameterTypes":["java.lang.String","java.lang.String"] }, {"name":"transform","parameterTypes":["java.lang.Module","java.lang.ClassLoader","java.lang.String","java.lang.Class","java.security.ProtectionDomain","byte[]","boolean"] }]
},
{
"name":"sun.management.VMManagementImpl",
"fields":[{"name":"compTimeMonitoringSupport"}, {"name":"currentThreadCpuTimeSupport"}, {"name":"objectMonitorUsageSupport"}, {"name":"otherThreadCpuTimeSupport"}, {"name":"remoteDiagnosticCommandsSupport"}, {"name":"synchronizerUsageSupport"}, {"name":"threadAllocatedMemorySupport"}, {"name":"threadContentionMonitoringSupport"}]
}
]

View File

@ -0,0 +1,8 @@
[
{
"type":"agent-extracted",
"classes":[
]
}
]

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