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
119 changed files with 8960 additions and 1164 deletions

2
.gitignore vendored
View File

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

View File

@ -6,12 +6,10 @@ notifications:
on_success: change
on_failure: always
dist: trusty
language: java
jdk:
- openjdk10
- 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.
Additionally, Nacos Spring Boot Project already supports native-image.
## Samples
- [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 AOT Sample](https://github.com/nacos-group/nacos-spring-boot-project/tree/master/nacos-spring-boot-samples/nacos-aot-sample)
## Dependencies & Compatibility
**master branch**
**Version: 0.2.x / 2.x.x ( branch master )**
| Dependencies | Compatibility |
| -------------- | ------------- |
| Java | 1.8+ |
| 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 |
| -------------- | ------------- |
| Java | 1.7+ |
| Spring Boot | 1.4.1.RELEASE |
| Nacos-Spring-Context | 1.1.0 |
## 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
<dependencies>
...
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-config-spring-boot-starter</artifactId>
<version>${latest.version}</version>
</dependency>
...
</dependencies>
```
- [Nacos AOT Quick Start](https://github.com/nacos-group/nacos-spring-boot-project/blob/master/NACOS-AOT-QUICK-START.md)
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 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
* [Alibaba Nacos](https://github.com/alibaba/nacos)

View File

@ -18,7 +18,7 @@
<parent>
<artifactId>nacos-spring-boot-parent</artifactId>
<groupId>com.alibaba.boot</groupId>
<version>0.1.6</version>
<version>${revision}</version>
<relativePath>../nacos-spring-boot-parent/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -81,8 +81,20 @@
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId>
<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>
<!-- Test Dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>

View File

@ -17,11 +17,8 @@
package com.alibaba.boot.nacos.actuate.autoconfigure;
import com.alibaba.boot.nacos.actuate.endpoint.NacosConfigEndpoint;
import com.alibaba.boot.nacos.config.NacosConfigConstants;
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.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -33,12 +30,11 @@ import org.springframework.context.annotation.Configuration;
* @see Endpoint
*/
@Configuration
@ConditionalOnClass(Endpoint.class)
public class NacosConfigEndpointAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnEnabledEndpoint(NacosConfigConstants.ENDPOINT_PREFIX)
@ConditionalOnAvailableEndpoint
public NacosConfigEndpoint nacosEndpoint() {
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.autoconfigure.NacosConfigAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.ConditionalOnEnabledHealthIndicator;
import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
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.config.NacosConfigConstants;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.config.annotation.NacosConfigListener;
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.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.StringUtils;
import org.w3c.dom.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
import org.springframework.boot.actuate.endpoint.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
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>
* @see Endpoint
*/
public class NacosConfigEndpoint extends AbstractEndpoint<Map<String, Object>>
@Endpoint(id = NacosConfigConstants.ENDPOINT_PREFIX)
public class NacosConfigEndpoint
implements ApplicationListener<NacosConfigMetadataEvent> {
@Autowired
private ApplicationContext applicationContext;
private Map<String, JSONObject> nacosConfigMetadataMap = new HashMap<>();
private Map<String, JsonNode> nacosConfigMetadataMap = new HashMap<>(8);
public NacosConfigEndpoint() {
super(NacosConfigConstants.ENDPOINT_PREFIX);
}
@Override
@ReadOperation
public Map<String, Object> invoke() {
Map<String, Object> result = new HashMap<>(8);
@ -85,37 +84,37 @@ public class NacosConfigEndpoint extends AbstractEndpoint<Map<String, Object>>
public void onApplicationEvent(NacosConfigMetadataEvent event) {
String key = buildMetadataKey(event);
if (StringUtils.isNotEmpty(key) && !nacosConfigMetadataMap.containsKey(key)) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("groupId", event.getGroupId());
jsonObject.put("dataId", event.getDataId());
ObjectNode jsonNode = JacksonUtils.createEmptyJsonNode();
jsonNode.put("groupId", event.getGroupId());
jsonNode.put("dataId", event.getDataId());
if (ClassUtils.isAssignable(event.getSource().getClass(),
AnnotationMetadata.class)) {
jsonObject.put("origin", "NacosPropertySource");
jsonObject.put("target",
jsonNode.put("origin", "NacosPropertySource");
jsonNode.put("target",
((AnnotationMetadata) event.getSource()).getClassName());
}
else if (ClassUtils.isAssignable(event.getSource().getClass(),
NacosConfigListener.class)) {
jsonObject.put("origin", "NacosConfigListener");
jsonNode.put("origin", "NacosConfigListener");
Method configListenerMethod = (Method) event.getAnnotatedElement();
jsonObject.put("target",
jsonNode.put("target",
configListenerMethod.getDeclaringClass().getName() + ":"
+ configListenerMethod.toString());
}
else if (ClassUtils.isAssignable(event.getSource().getClass(),
NacosConfigurationProperties.class)) {
jsonObject.put("origin", "NacosConfigurationProperties");
jsonObject.put("target", event.getBeanType().getName());
jsonNode.put("origin", "NacosConfigurationProperties");
jsonNode.put("target", event.getBeanType().getName());
}
else if (ClassUtils.isAssignable(event.getSource().getClass(),
Element.class)) {
jsonObject.put("origin", "NacosPropertySource");
jsonObject.put("target", event.getXmlResource().toString());
jsonNode.put("origin", "NacosPropertySource");
jsonNode.put("target", event.getXmlResource().toString());
}
else {
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 com.alibaba.boot.nacos.common.PropertiesUtils;
import com.alibaba.fastjson.JSON;
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.NacosServiceFactory;
import com.alibaba.nacos.spring.metadata.NacosServiceMetaData;
@ -38,6 +38,7 @@ import org.springframework.context.ApplicationContext;
* @see HealthIndicator
*/
public class NacosConfigHealthIndicator extends AbstractHealthIndicator {
@Autowired
private ApplicationContext applicationContext;
@ -53,7 +54,7 @@ public class NacosConfigHealthIndicator extends AbstractHealthIndicator {
NacosServiceMetaData nacosServiceMetaData = (NacosServiceMetaData) configService;
Properties properties = nacosServiceMetaData.getProperties();
builder.withDetail(
JSON.toJSONString(
JacksonUtils.toJson(
PropertiesUtils.extractSafeProperties(properties)),
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>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-parent</artifactId>
<version>0.1.6</version>
<version>${revision}</version>
<relativePath>../nacos-spring-boot-parent</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -27,6 +27,18 @@
<packaging>jar</packaging>
<name>Nacos Config Spring Boot AutoConfigure</name>
<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>
@ -54,11 +66,30 @@
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId>
<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>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-base</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-base</artifactId>
<artifactId>nacos-spring-boot-aot</artifactId>
<optional>true</optional>
</dependency>

View File

@ -25,7 +25,7 @@ import com.alibaba.nacos.spring.context.annotation.config.EnableNacosConfig;
*/
public interface NacosConfigConstants {
String ENDPOINT_PREFIX = "nacos_config";
String ENDPOINT_PREFIX = "nacos-config";
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>
* @since 0.1.3
* @since 0.2.3
*/
public class NacosBootConfigException extends RuntimeException {

View File

@ -17,13 +17,15 @@
package com.alibaba.boot.nacos.config.autoconfigure;
import java.util.Properties;
import java.util.function.Function;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.boot.nacos.config.util.Function;
import com.alibaba.boot.nacos.config.util.NacosConfigPropertiesUtils;
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.nacos.api.config.ConfigService;
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.util.NacosBeanUtils;
import org.slf4j.Logger;
@ -36,77 +38,67 @@ import org.springframework.core.env.ConfigurableEnvironment;
/**
* @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> {
private final Logger logger = LoggerFactory
.getLogger(NacosConfigApplicationInitializer.class);
private ConfigurableEnvironment environment;
.getLogger(NacosConfigApplicationContextInitializer.class);
private final NacosConfigEnvironmentProcessor processor;
private NacosConfigProperties nacosConfigProperties;
private final CacheableEventPublishingNacosServiceFactory singleton = CacheableEventPublishingNacosServiceFactory
.getSingleton();
private final Function<Properties, ConfigService> builder = new Function<Properties, ConfigService>() {
@Override
public ConfigService apply(Properties input) {
try {
return singleton.createConfigService(input);
}
catch (NacosException e) {
throw new NacosBootConfigException(
"ConfigService can't be created with properties : "
+ input,
e);
}
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;
public NacosConfigApplicationInitializer(
public NacosConfigApplicationContextInitializer(
NacosConfigEnvironmentProcessor configEnvironmentProcessor) {
this.processor = configEnvironmentProcessor;
}
@Override
public void initialize(ConfigurableApplicationContext context) {
singleton.setApplicationContext(context);
environment = context.getEnvironment();
nacosConfigProperties = NacosConfigPropertiesUtils
.buildNacosConfigProperties(environment);
final NacosConfigLoader configLoader = new NacosConfigLoader(
nacosConfigProperties, environment, builder);
final NacosConfigLoader configLoader = NacosConfigLoaderFactory.getSingleton(builder);
if (!processor.snapshotEnable()){
SnapShotSwitch.setIsSnapShot(false);
}
if (!enable()) {
logger.info("[Nacos Config Boot] : The preload configuration is not enabled");
}
else {
// If it opens the log level loading directly will cache
// DeferNacosPropertySource release
if (processor.enable()) {
processor.publishDeferService(context);
configLoader
.addListenerIfAutoRefreshed(processor.getDeferPropertySources());
}
else {
configLoader.loadConfig();
configLoader.loadConfig(environment, nacosConfigProperties);
configLoader.addListenerIfAutoRefreshed();
}
}
// Register global Nacos configuration metadata information
final ConfigurableListableBeanFactory factory = context.getBeanFactory();
if (!factory.containsSingleton(NacosBeanUtils.GLOBAL_NACOS_PROPERTIES_BEAN_NAME)) {
factory.registerSingleton(NacosBeanUtils.GLOBAL_NACOS_PROPERTIES_BEAN_NAME, configLoader.buildGlobalNacosProperties());
}
}
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;
import com.alibaba.boot.nacos.aot.context.EnableNacosConfigAotProcessor;
import com.alibaba.boot.nacos.config.NacosConfigConstants;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
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)
@ConditionalOnMissingBean(name = CONFIG_GLOBAL_NACOS_PROPERTIES_BEAN_NAME)
@EnableNacosConfig
@EnableConfigurationProperties(value = NacosConfigProperties.class)
@ConditionalOnClass(name = "org.springframework.boot.bind.RelaxedDataBinder")
@Import(value = { NacosConfigBootBeanDefinitionRegistrar.class })
@ConditionalOnClass(name = "org.springframework.boot.context.properties.bind.Binder")
@Import(value = { NacosConfigBootBeanDefinitionRegistrar.class, EnableNacosConfigAotProcessor.class })
@EnableNacosConfig
public class NacosConfigAutoConfiguration {
}

View File

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

View File

@ -20,19 +20,21 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Properties;
import java.util.function.Function;
import com.alibaba.boot.nacos.config.properties.NacosConfigProperties;
import com.alibaba.boot.nacos.config.util.Function;
import com.alibaba.boot.nacos.config.util.NacosConfigPropertiesUtils;
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.log.LogAutoFreshProcess;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.spring.factory.CacheableEventPublishingNacosServiceFactory;
import com.alibaba.nacos.spring.util.NacosUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.context.ApplicationContext;
@ -40,61 +42,60 @@ import org.springframework.core.Ordered;
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>
* @since 0.1.3
* @since 0.2.3
*/
public class NacosConfigEnvironmentProcessor
implements EnvironmentPostProcessor, Ordered {
private final Logger logger = LoggerFactory
.getLogger(NacosConfigEnvironmentProcessor.class);
private final CacheableEventPublishingNacosServiceFactory nacosServiceFactory = CacheableEventPublishingNacosServiceFactory
.getSingleton();
private final LinkedList<NacosConfigLoader.DeferNacosPropertySource> deferPropertySources = new LinkedList<>();
private final Map<String, ConfigService> serviceCache = new HashMap<>(8);
private final LinkedList<NacosConfigLoader.DeferNacosPropertySource> deferPropertySources = new LinkedList<>();
private NacosConfigProperties nacosConfigProperties;
private final Function<Properties, ConfigService> builder = new Function<Properties, ConfigService>() {
@Override
public ConfigService apply(Properties input) {
try {
final String key = NacosUtils.identify(input);
ConfigService service = serviceCache.get(key);
if (service != null) {
return serviceCache.get(key);
}
service = NacosFactory.createConfigService(input);
serviceCache.put(key, service);
return nacosServiceFactory.deferCreateService(service, input);
}
catch (NacosException e) {
throw new NacosBootConfigException(
"ConfigService can't be created with properties : " + input, e);
// Because ApplicationContext has not been injected at preload time, need to manually
// cache the created Service to prevent duplicate creation
private final Function<Properties, ConfigService> builder = properties -> {
try {
final String key = NacosUtils.identify(properties);
if (serviceCache.containsKey(key)) {
return serviceCache.get(key);
}
final ConfigService configService = NacosFactory
.createConfigService(properties);
serviceCache.put(key, configService);
return nacosServiceFactory.deferCreateService(configService, properties);
}
catch (NacosException e) {
throw new NacosBootConfigException(
"ConfigService can't be created with properties : " + properties, e);
}
};
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment,
SpringApplication application) {
application.addInitializers(new NacosConfigApplicationInitializer(this));
application.addInitializers(new NacosConfigApplicationContextInitializer(this));
nacosConfigProperties = NacosConfigPropertiesUtils
.buildNacosConfigProperties(environment);
if (enable()) {
System.out.println(
"[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) {
final NacosConfigLoader configLoader = new NacosConfigLoader(nacosConfigProperties,
environment, builder);
configLoader.loadConfig();
// set defer nacosPropertySource
private void loadConfig(NacosConfigLoader configLoader, ConfigurableEnvironment environment, NacosConfigProperties nacosConfigProperties) {
configLoader.loadConfig(environment, nacosConfigProperties);
// set defer NacosPropertySource
deferPropertySources.addAll(configLoader.getNacosPropertySources());
}
@ -103,22 +104,29 @@ public class NacosConfigEnvironmentProcessor
&& nacosConfigProperties.getBootstrap().isLogEnable();
}
boolean snapshotEnable() {
return nacosConfigProperties != null
&& nacosConfigProperties.getBootstrap().isSnapshotEnable();
}
LinkedList<NacosConfigLoader.DeferNacosPropertySource> getDeferPropertySources() {
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) {
try {
nacosServiceFactory.publishDeferService(context);
serviceCache.clear();
}
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 - 5;
}
}
}

View File

@ -16,43 +16,74 @@
*/
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.annotation.NacosConfigurationProperties;
import com.alibaba.nacos.spring.context.properties.config.NacosConfigurationPropertiesBinder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.nacos.spring.core.env.NacosPropertySource;
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 static com.alibaba.nacos.spring.util.NacosUtils.toProperties;
import org.springframework.core.ResolvableType;
import org.springframework.core.env.StandardEnvironment;
/**
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since 0.1.2
* @since 0.2.2
*/
public class NacosBootConfigurationPropertiesBinder
extends NacosConfigurationPropertiesBinder {
private ConfigurableApplicationContext context;
private final ConfigurableApplicationContext applicationContext;
private final StandardEnvironment environment = new StandardEnvironment();
public NacosBootConfigurationPropertiesBinder(
ConfigurableApplicationContext applicationContext) {
super(applicationContext);
this.context = applicationContext;
this.applicationContext = applicationContext;
}
@Override
protected void doBind(Object bean, String beanName, String dataId, String groupId,
String configType, NacosConfigurationProperties properties, String content,
ConfigService configService) {
Properties prop = toProperties(dataId, groupId, content, configType);
BinderUtils.bind(bean, properties.prefix(), prop);
publishBoundEvent(bean, beanName, dataId, groupId, properties, content,
configService);
publishMetadataEvent(bean, beanName, dataId, groupId, properties);
synchronized (this) {
String name = "nacos-bootstrap-" + beanName;
NacosPropertySource propertySource = new NacosPropertySource(dataId, groupId, name, content, configType);
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);
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.List;
import java.util.Objects;
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.config.ConfigType;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.util.Assert;
@ -60,7 +61,7 @@ public class NacosConfigProperties {
private String group = Constants.DEFAULT_GROUP;
private ConfigType type;
private ConfigType type = ConfigType.PROPERTIES;
private String maxRetry;
@ -74,7 +75,9 @@ public class NacosConfigProperties {
private String password;
@JSONField(serialize = false)
private boolean remoteFirst = false;
@JsonIgnore
private List<Config> extConfig = new ArrayList<>();
@NestedConfigurationProperty
@ -233,6 +236,14 @@ public class NacosConfigProperties {
this.enableRemoteSyncConfig = enableRemoteSyncConfig;
}
public boolean isRemoteFirst() {
return remoteFirst;
}
public void setRemoteFirst(boolean remoteFirst) {
this.remoteFirst = remoteFirst;
}
public List<Config> getExtConfig() {
return extConfig;
}
@ -249,11 +260,39 @@ public class NacosConfigProperties {
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 {
private boolean enable = false;
private boolean enable;
private boolean logEnable = false;
private boolean logEnable;
private boolean snapshotEnable;
public boolean isEnable() {
return enable;
@ -270,6 +309,24 @@ public class NacosConfigProperties {
public void setLogEnable(boolean 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 {
@ -446,33 +503,25 @@ public class NacosConfigProperties {
@Override
public String toString() {
return "Config{" + "serverAddr='" + serverAddr + '\'' + ", endpoint='"
+ endpoint + '\'' + ", namespace='" + namespace + '\''
+ ", accessKey='" + accessKey + '\'' + ", secretKey='" + secretKey
+ '\'' + ", ramRoleName='" + ramRoleName + '\'' + ", dataId='"
+ dataId + '\'' + ", dataIds='" + dataIds + '\'' + ", group='" + group
+ '\'' + ", type=" + type + ", maxRetry='" + maxRetry + '\''
+ ", configLongPollTimeout='" + configLongPollTimeout + '\''
+ ", configRetryTime='" + configRetryTime + '\'' + ", autoRefresh="
+ autoRefresh + ", enableRemoteSyncConfig=" + enableRemoteSyncConfig
+ ", username='" + username + '\'' + ", password='" + password + '\''
+ '}';
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();
}
}
@Override
public String toString() {
return "NacosConfigProperties{" + "serverAddr='" + serverAddr + '\''
+ ", contextPath='" + contextPath + '\'' + ", encode='" + encode + '\''
+ ", endpoint='" + endpoint + '\'' + ", namespace='" + namespace + '\''
+ ", accessKey='" + accessKey + '\'' + ", secretKey='" + secretKey + '\''
+ ", ramRoleName='" + ramRoleName + '\'' + ", autoRefresh=" + autoRefresh
+ ", dataId='" + dataId + '\'' + ", dataIds='" + dataIds + '\''
+ ", group='" + group + '\'' + ", type=" + type + ", maxRetry='"
+ maxRetry + '\'' + ", configLongPollTimeout='" + configLongPollTimeout
+ '\'' + ", configRetryTime='" + configRetryTime + '\''
+ ", enableRemoteSyncConfig=" + enableRemoteSyncConfig + ", username='"
+ username + '\'' + ", password='" + password + '\'' + ", extConfig="
+ extConfig + ", bootstrap=" + bootstrap + '}';
}
}
}

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>
* @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 ConfigurableEnvironment environment;
@ -44,33 +44,33 @@ public class AttributeExtractTask implements Callable<Map<String, Object>> {
}
@Override
public Map<String, Object> call() throws Exception {
List<Map<String, Object>> defer = new LinkedList<>();
public Map<String, String> call() throws Exception {
List<Map<String, String>> defer = new LinkedList<>();
MutablePropertySources mutablePropertySources = environment.getPropertySources();
for (PropertySource propertySource : mutablePropertySources) {
calculate(propertySource.getSource(), defer);
}
Map<String, Object> result = new HashMap<>(32);
Map<String, String> result = new HashMap<>(32);
Collections.reverse(defer);
for (Map<String, Object> item : defer) {
for (Map<String, String> item : defer) {
result.putAll(item);
}
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) {
calculate(((PropertySource) source).getSource(), defer);
}
if (source instanceof Map) {
Map<String, Object> map = new HashMap<>(8);
Map<String, String> map = new HashMap<>(8);
for (Object entry : ((Map) source).entrySet()) {
Map.Entry<Object, Object> element = (Map.Entry<Object, Object>) entry;
String key = String.valueOf(element.getKey());
if (key.startsWith(prefix)) {
map.put(key, element.getValue());
map.put(key, String.valueOf(element.getValue()));
}
}
if (!map.isEmpty()) {

View File

@ -20,7 +20,10 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
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.nacos.api.config.ConfigService;
@ -28,54 +31,57 @@ import com.alibaba.nacos.api.config.ConfigType;
import com.alibaba.nacos.spring.core.env.NacosPropertySource;
import com.alibaba.nacos.spring.core.env.NacosPropertySourcePostProcessor;
import com.alibaba.nacos.spring.util.NacosUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.ConfigurableEnvironment;
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;
/**
* @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 NacosConfigLoader {
private final Logger logger = LoggerFactory.getLogger(NacosConfigLoader.class);
private final NacosConfigProperties nacosConfigProperties;
private final ConfigurableEnvironment environment;
private Function<Properties, ConfigService> builder;
private List<DeferNacosPropertySource> nacosPropertySources = new LinkedList<>();
private Properties globalProperties = new Properties();
public NacosConfigLoader(NacosConfigProperties nacosConfigProperties,
ConfigurableEnvironment environment,
Function<Properties, ConfigService> builder) {
this.nacosConfigProperties = nacosConfigProperties;
this.environment = environment;
private final Function<Properties, ConfigService> builder;
private final List<DeferNacosPropertySource> nacosPropertySources = new LinkedList<>();
public NacosConfigLoader(Function<Properties, ConfigService> builder) {
this.builder = builder;
}
public void loadConfig() {
Properties globalProperties = buildGlobalNacosProperties();
public void loadConfig(ConfigurableEnvironment environment, NacosConfigProperties nacosConfigProperties) {
globalProperties = buildGlobalNacosProperties(environment, nacosConfigProperties);
MutablePropertySources mutablePropertySources = environment.getPropertySources();
List<NacosPropertySource> sources = reqGlobalNacosConfig(globalProperties,
nacosConfigProperties.getType());
List<NacosPropertySource> sources = reqGlobalNacosConfig(environment, globalProperties, nacosConfigProperties);
for (NacosConfigProperties.Config config : nacosConfigProperties.getExtConfig()) {
List<NacosPropertySource> elements = reqSubNacosConfig(config,
List<NacosPropertySource> elements = reqSubNacosConfig(environment, config,
globalProperties, config.getType());
sources.addAll(sources.size(), elements);
sources.addAll(elements);
}
for (NacosPropertySource propertySource : sources) {
mutablePropertySources.addLast(propertySource);
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) {
mutablePropertySources.addLast(propertySource);
}
}
}
public Properties buildGlobalNacosProperties() {
return NacosPropertiesBuilder.buildNacosProperties(
environment,
public Properties buildGlobalNacosProperties(ConfigurableEnvironment environment, NacosConfigProperties nacosConfigProperties) {
return NacosPropertiesBuilder.buildNacosProperties(environment,
nacosConfigProperties.getServerAddr(),
nacosConfigProperties.getNamespace(), nacosConfigProperties.getEndpoint(),
nacosConfigProperties.getSecretKey(),
@ -84,39 +90,35 @@ public class NacosConfigLoader {
nacosConfigProperties.getConfigLongPollTimeout(),
nacosConfigProperties.getConfigRetryTime(),
nacosConfigProperties.getMaxRetry(),
nacosConfigProperties.getContextPath(),
nacosConfigProperties.isEnableRemoteSyncConfig(),
nacosConfigProperties.getUsername(), nacosConfigProperties.getPassword());
}
private Properties buildSubNacosProperties(Properties globalProperties,
private Properties buildSubNacosProperties(ConfigurableEnvironment environment, Properties globalProperties,
NacosConfigProperties.Config config) {
return getProperties(globalProperties, config);
}
private Properties getProperties(Properties globalProperties,
NacosConfigProperties.Config config) {
if (StringUtils.isEmpty(config.getServerAddr())) {
return globalProperties;
}
Properties sub = NacosPropertiesBuilder.buildNacosProperties(
environment,
Properties sub = NacosPropertiesBuilder.buildNacosProperties(environment,
config.getServerAddr(), config.getNamespace(), config.getEndpoint(),
config.getSecretKey(), config.getAccessKey(), config.getRamRoleName(),
config.getConfigLongPollTimeout(), config.getConfigRetryTime(),
config.getMaxRetry(), config.isEnableRemoteSyncConfig(),
config.getMaxRetry(),null, config.isEnableRemoteSyncConfig(),
config.getUsername(), config.getPassword());
NacosPropertiesBuilder.merge(sub, globalProperties);
return sub;
}
private List<NacosPropertySource> reqGlobalNacosConfig(Properties globalProperties,
ConfigType type) {
private List<NacosPropertySource> reqGlobalNacosConfig(ConfigurableEnvironment environment, Properties globalProperties,
NacosConfigProperties nacosConfigProperties) {
List<String> dataIds = new ArrayList<>();
// 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
.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 {
dataIds.add(nacosConfigProperties.getDataId());
@ -124,18 +126,18 @@ public class NacosConfigLoader {
final String groupName = environment
.resolvePlaceholders(nacosConfigProperties.getGroup());
final boolean isAutoRefresh = nacosConfigProperties.isAutoRefresh();
return new ArrayList<>(Arrays.asList(reqNacosConfig(globalProperties,
dataIds.toArray(new String[0]), groupName, type, isAutoRefresh)));
return new ArrayList<>(Arrays.asList(reqNacosConfig(environment, globalProperties,
dataIds.toArray(new String[0]), groupName, nacosConfigProperties.getType(), isAutoRefresh)));
}
private List<NacosPropertySource> reqSubNacosConfig(
private List<NacosPropertySource> reqSubNacosConfig(ConfigurableEnvironment environment,
NacosConfigProperties.Config config, Properties globalProperties,
ConfigType type) {
Properties subConfigProperties = buildSubNacosProperties(globalProperties,
Properties subConfigProperties = buildSubNacosProperties(environment, globalProperties,
config);
ArrayList<String> dataIds = new ArrayList<>();
if (StringUtils.isEmpty(config.getDataId())) {
final String ids = environment.resolvePlaceholders(config.getDataId());
if (!StringUtils.hasLength(config.getDataId())) {
final String ids = environment.resolvePlaceholders(config.getDataIds());
dataIds.addAll(Arrays.asList(ids.split(",")));
}
else {
@ -143,17 +145,18 @@ public class NacosConfigLoader {
}
final String groupName = environment.resolvePlaceholders(config.getGroup());
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)));
}
private NacosPropertySource[] reqNacosConfig(Properties configProperties,
private NacosPropertySource[] reqNacosConfig(ConfigurableEnvironment environment, Properties configProperties,
String[] dataIds, String groupId, ConfigType type, boolean isAutoRefresh) {
final NacosPropertySource[] propertySources = new NacosPropertySource[dataIds.length];
for (int i = 0; i < dataIds.length; i++) {
if (StringUtils.isEmpty(dataIds[i])) {
if (!StringUtils.hasLength(dataIds[i])) {
continue;
}
// Remove excess Spaces
final String dataId = environment.resolvePlaceholders(dataIds[i].trim());
final String config = NacosUtils.getContent(builder.apply(configProperties),
dataId, groupId);
@ -165,9 +168,8 @@ public class NacosConfigLoader {
nacosPropertySource.setType(type.getType());
nacosPropertySource.setGroupId(groupId);
nacosPropertySource.setAutoRefreshed(isAutoRefresh);
logger.info(
"load config from nacos, data-id is : [{}], group is : [{}], config-text is : [{}]",
dataId, groupId, config);
logger.info("load config from nacos, data-id is : {}, group is : {}",
nacosPropertySource.getDataId(), nacosPropertySource.getGroupId());
propertySources[i] = nacosPropertySource;
DeferNacosPropertySource defer = new DeferNacosPropertySource(
nacosPropertySource, configProperties, environment);
@ -194,6 +196,11 @@ public class NacosConfigLoader {
return nacosPropertySources;
}
public Properties getGlobalProperties() {
return globalProperties;
}
// 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
// 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;
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.properties.NacosConfigProperties;
import com.alibaba.nacos.api.config.ConfigService;
import org.slf4j.Logger;
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 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>
* @since 0.1.3
* @since 0.2.3
*/
public class NacosConfigPropertiesUtils {
private static final String PROPERTIES_PREFIX = "nacos";
private static final Logger logger = LoggerFactory
.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(
ConfigurableEnvironment environment) {
NacosConfigProperties bean = new NacosConfigProperties();
AttributeExtractTask task = new AttributeExtractTask(PROPERTIES_PREFIX,
environment);
try {
Properties properties = new Properties();
properties.putAll(task.call());
BinderUtils.bind(bean, NacosConfigConstants.PREFIX, properties);
}
catch (Exception e) {
throw new RuntimeException(e);
}
logger.debug("nacosConfigProperties : {}", bean);
return bean;
NacosConfigProperties nacosConfigProperties = new NacosConfigProperties();
Binder binder = Binder.get(environment);
ResolvableType type = ResolvableType.forClass(NacosConfigProperties.class);
Bindable<?> target = Bindable.of(type).withExistingValue(nacosConfigProperties);
binder.bind(NacosConfigConstants.PREFIX, target);
logger.info("nacosConfigProperties : {}", nacosConfigProperties);
return nacosConfigProperties;
}
}

View File

@ -27,55 +27,39 @@ import org.springframework.util.CollectionUtils;
/**
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since 0.1.3
* @since 0.2.3
*/
public class NacosPropertiesBuilder {
public static Properties buildNacosProperties(Environment environment,
String serverAddr, String namespaceId, String endpoint, String secretKey,
String accessKey, String ramRoleName, String configLongPollTimeout,
String configRetryTimeout, String maxRetry, boolean enableRemoteSyncConfig,
String configRetryTimeout, String maxRetry,String contextPath, boolean enableRemoteSyncConfig,
String username, String password) {
Properties properties = new Properties();
if (StringUtils.isNotEmpty(serverAddr)) {
properties.put(PropertyKeyConst.SERVER_ADDR, environment.resolvePlaceholders(serverAddr));
}
if (StringUtils.isNotEmpty(namespaceId)) {
properties.put(PropertyKeyConst.NAMESPACE, environment.resolvePlaceholders(namespaceId));
}
if (StringUtils.isNotEmpty(endpoint)) {
properties.put(PropertyKeyConst.ENDPOINT, environment.resolvePlaceholders(endpoint));
}
if (StringUtils.isNotEmpty(secretKey)) {
properties.put(PropertyKeyConst.SECRET_KEY, environment.resolvePlaceholders(secretKey));
}
if (StringUtils.isNotEmpty(accessKey)) {
properties.put(PropertyKeyConst.ACCESS_KEY, environment.resolvePlaceholders(accessKey));
}
if (StringUtils.isNoneEmpty(ramRoleName)) {
properties.put(PropertyKeyConst.RAM_ROLE_NAME, environment.resolvePlaceholders(ramRoleName));
}
if (StringUtils.isNotEmpty(configLongPollTimeout)) {
properties.put(PropertyKeyConst.CONFIG_LONG_POLL_TIMEOUT,
environment.resolvePlaceholders(configLongPollTimeout));
}
if (StringUtils.isNotEmpty(configRetryTimeout)) {
properties.put(PropertyKeyConst.CONFIG_RETRY_TIME, environment.resolvePlaceholders(configRetryTimeout));
}
if (StringUtils.isNotEmpty(maxRetry)) {
properties.put(PropertyKeyConst.MAX_RETRY, environment.resolvePlaceholders(maxRetry));
}
if (StringUtils.isNotBlank(username)) {
properties.put(PropertyKeyConst.USERNAME, environment.resolvePlaceholders(username));
}
if (StringUtils.isNotBlank(password)) {
properties.put(PropertyKeyConst.PASSWORD, environment.resolvePlaceholders(password));
}
processPropertiesData(properties,environment,serverAddr,PropertyKeyConst.SERVER_ADDR);
processPropertiesData(properties,environment,namespaceId,PropertyKeyConst.NAMESPACE);
processPropertiesData(properties,environment,endpoint,PropertyKeyConst.ENDPOINT);
processPropertiesData(properties,environment,secretKey,PropertyKeyConst.SECRET_KEY);
processPropertiesData(properties,environment,accessKey,PropertyKeyConst.ACCESS_KEY);
processPropertiesData(properties,environment,ramRoleName,PropertyKeyConst.RAM_ROLE_NAME);
processPropertiesData(properties,environment,configLongPollTimeout,PropertyKeyConst.CONFIG_LONG_POLL_TIMEOUT);
processPropertiesData(properties,environment,configRetryTimeout,PropertyKeyConst.CONFIG_RETRY_TIME);
processPropertiesData(properties,environment,contextPath,PropertyKeyConst.CONTEXT_PATH);
processPropertiesData(properties,environment,maxRetry,PropertyKeyConst.MAX_RETRY);
processPropertiesData(properties,environment,username,PropertyKeyConst.USERNAME);
processPropertiesData(properties,environment,password,PropertyKeyConst.PASSWORD);
properties.put(PropertyKeyConst.ENABLE_REMOTE_SYNC_CONFIG,
String.valueOf(enableRemoteSyncConfig));
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) {
@ -93,4 +77,4 @@ public class NacosPropertiesBuilder {
}
}
}

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
* limitations under the License.
*/
package com.alibaba.boot.nacos.config.util;
package com.alibaba.boot.nacos.config.util.editor;
import java.util.Properties;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.boot.bind.RelaxedDataBinder;
import java.beans.PropertyEditorSupport;
/**
* @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) {
RelaxedDataBinder binder = new RelaxedDataBinder(obj, prefix);
binder.bind(new MutablePropertyValues(properties));
return obj;
@Override
public void setValue(Object value) {
if (value == null) {
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>
* @since 0.1.3
* @since 0.2.3
*/
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 String[] tags;
private Object value;
@ -153,5 +153,4 @@ public class NacosEnumEditor implements PropertyEditor {
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=\
com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration
#org.springframework.context.ApplicationContextInitializer=\
# com.alibaba.boot.nacos.config.autoconfigure.NacosConfigApplicationContextInitializer
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 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.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.annotation.NacosInjected;
@ -84,4 +85,8 @@ public class NacosConfigAutoConfigurationTest {
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>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-parent</artifactId>
<version>0.1.6</version>
<version>${revision}</version>
<relativePath>../nacos-spring-boot-parent</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -34,13 +34,24 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<scope>true</scope>
</dependency>
<!-- Nacos -->
<dependency>
<groupId>com.alibaba.nacos</groupId>
<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>
@ -53,5 +64,10 @@
<artifactId>nacos-spring-boot-base</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-aot</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -18,7 +18,7 @@
<parent>
<artifactId>nacos-spring-boot-parent</artifactId>
<groupId>com.alibaba.boot</groupId>
<version>0.1.6</version>
<version>${revision}</version>
<relativePath>../nacos-spring-boot-parent/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -81,7 +81,20 @@
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId>
<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>
<!-- Test Dependencies -->
<dependency>

View File

@ -16,12 +16,9 @@
*/
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 org.springframework.boot.actuate.condition.ConditionalOnEnabledEndpoint;
import org.springframework.boot.actuate.endpoint.Endpoint;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -33,12 +30,11 @@ import org.springframework.context.annotation.Configuration;
* @see Endpoint
*/
@Configuration
@ConditionalOnClass(Endpoint.class)
public class NacosDiscoveryEndpointsAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnEnabledEndpoint(NacosDiscoveryConstants.ENDPOINT_PREFIX)
@ConditionalOnAvailableEndpoint
public NacosDiscoveryEndpoint 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.autoconfigure.NacosDiscoveryAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.ConditionalOnEnabledHealthIndicator;
import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
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.discovery.NacosDiscoveryConstants;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
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.NacosServiceFactory;
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.boot.actuate.endpoint.AbstractEndpoint;
import org.springframework.boot.actuate.endpoint.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.context.ApplicationContext;
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>
* @see Endpoint
*/
public class NacosDiscoveryEndpoint extends AbstractEndpoint<Map<String, Object>> {
@Endpoint(id = NacosDiscoveryConstants.ENDPOINT_PREFIX)
public class NacosDiscoveryEndpoint {
@Autowired
private ApplicationContext applicationContext;
private static final Integer PAGE_SIZE = 100;
public NacosDiscoveryEndpoint() {
super(NacosDiscoveryConstants.ENDPOINT_PREFIX);
}
@Override
@ReadOperation
public Map<String, Object> invoke() {
Map<String, Object> result = new HashMap<>(8);
@ -63,19 +61,18 @@ public class NacosDiscoveryEndpoint extends AbstractEndpoint<Map<String, Object>
NacosServiceFactory nacosServiceFactory = CacheableEventPublishingNacosServiceFactory
.getSingleton();
;
JSONArray array = new JSONArray();
ArrayNode array = JacksonUtils.createEmptyArrayNode();
for (NamingService namingService : nacosServiceFactory.getNamingServices()) {
JSONObject jsonObject = new JSONObject();
ObjectNode jsonObject = JacksonUtils.createEmptyJsonNode();
try {
jsonObject.put("servicesOfServer",
jsonObject.putPOJO("servicesOfServer",
namingService.getServicesOfServer(0, PAGE_SIZE));
jsonObject.put("subscribeServices", namingService.getSubscribeServices());
jsonObject.putPOJO("subscribeServices", namingService.getSubscribeServices());
array.add(jsonObject);
}
catch (Exception e) {
jsonObject.put("serverStatus", namingService.getServerStatus()
jsonObject.put("serverStatus", namingService.getServerStatus() + ": "
+ NacosUtils.SEPARATOR + e.getMessage());
}
}

View File

@ -19,8 +19,8 @@ package com.alibaba.boot.nacos.discovery.actuate.health;
import java.util.Properties;
import com.alibaba.boot.nacos.common.PropertiesUtils;
import com.alibaba.fastjson.JSON;
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.NacosServiceFactory;
import com.alibaba.nacos.spring.metadata.NacosServiceMetaData;
@ -54,11 +54,11 @@ public class NacosDiscoveryHealthIndicator extends AbstractHealthIndicator {
NacosServiceMetaData nacosServiceMetaData = (NacosServiceMetaData) namingService;
Properties properties = nacosServiceMetaData.getProperties();
builder.withDetail(
JSON.toJSONString(
JacksonUtils.toJson(
PropertiesUtils.extractSafeProperties(properties)),
namingService.getServerStatus());
}
if (!namingService.getServerStatus().toLowerCase().equals(UP_STATUS)) {
if (!namingService.getServerStatus().equalsIgnoreCase(UP_STATUS)) {
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.autoconfigure.NacosDiscoveryAutoConfiguration;
import com.alibaba.nacos.api.PropertyKeyConst;
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.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
/**
@ -38,7 +36,6 @@ import org.springframework.test.context.junit4.SpringRunner;
* @see NacosDiscoveryEndpoint
*/
@RunWith(SpringRunner.class)
@TestPropertySource(properties = { "nacos.discovery.server-addr=localhost" })
@SpringBootTest(classes = { NacosDiscoveryEndpoint.class,
NacosDiscoveryAutoConfiguration.class })
public class NacosDiscoveryEndpointTest {
@ -53,8 +50,7 @@ public class NacosDiscoveryEndpointTest {
HashMap nacosDiscoveryGlobalProperties = (HashMap) metadata
.get("nacosDiscoveryGlobalProperties");
Assert.assertEquals("localhost",
nacosDiscoveryGlobalProperties.get(PropertyKeyConst.SERVER_ADDR));
Assert.assertNotNull(nacosDiscoveryGlobalProperties);
}
}

View File

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

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-parent</artifactId>
<version>0.1.6</version>
<version>${revision}</version>
<relativePath>../nacos-spring-boot-parent</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -54,11 +54,30 @@
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId>
<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>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-base</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-base</artifactId>
<artifactId>nacos-spring-boot-aot</artifactId>
<optional>true</optional>
</dependency>

View File

@ -25,9 +25,10 @@ import com.alibaba.nacos.spring.context.annotation.discovery.EnableNacosDiscover
*/
public interface NacosDiscoveryConstants {
String ENDPOINT_PREFIX = "nacos_discovery";
String PREFIX = "nacos.discovery";
String ENDPOINT_PREFIX = "nacos-discovery";
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>
* @since 0.1.4
* @since 0.2.4
*/
public class AutoDeregisterException extends RuntimeException {
public AutoDeregisterException(String message) {
super(message);
}
public AutoDeregisterException(Throwable 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>
* @since 0.1.3
* @since 0.2.3
*/
public class AutoRegisterException extends RuntimeException {
public AutoRegisterException(String message) {
super(message);
}
public AutoRegisterException(Throwable cause) {
super(cause);
}

View File

@ -16,6 +16,7 @@
*/
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.properties.NacosDiscoveryProperties;
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.context.annotation.Bean;
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;
@ -38,7 +40,8 @@ import static com.alibaba.nacos.spring.util.NacosBeanUtils.DISCOVERY_GLOBAL_NACO
@ConditionalOnMissingBean(name = DISCOVERY_GLOBAL_NACOS_PROPERTIES_BEAN_NAME)
@EnableNacosDiscovery
@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 {
@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.exception.NacosException;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.event.ContextClosedEvent;
import org.springframework.stereotype.Component;
/**
* @author <a href="mailto:liaochunyhm@live.com">liaochuntao</a>
* @since 0.1.4
* @since 0.2.4
*/
@Component
public class NacosDiscoveryAutoDeregister
@ -47,13 +47,13 @@ public class NacosDiscoveryAutoDeregister
private NamingService namingService;
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;
public NacosDiscoveryAutoDeregister(NacosDiscoveryProperties discoveryProperties,
EmbeddedServletContainer webServer) {
WebServer webServer) {
this.discoveryProperties = discoveryProperties;
this.webServer = webServer;
}
@ -74,15 +74,20 @@ public class NacosDiscoveryAutoDeregister
register.setPort(webServer.getPort());
}
String serviceName = StringUtils.isEmpty(register.getServiceName())
? applicationName
: register.getServiceName();
String serviceName = register.getServiceName();
if (StringUtils.isEmpty(serviceName)){
if (StringUtils.isEmpty(applicationName)){
throw new AutoDeregisterException("serviceName notNull");
}
serviceName = applicationName;
}
try {
namingService.deregisterInstance(serviceName, register.getGroupName(),
register);
logger.info("Finished auto deregister service : {}, ip : {}, port : {}",
register.getServiceName(), register.getIp(), register.getPort());
serviceName, register.getIp(), register.getPort());
}
catch (NacosException e) {
throw new AutoDeregisterException(e);

View File

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

View File

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

View File

@ -7,4 +7,4 @@
"type": "com.alibaba.nacos.api.naming.pojo.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

@ -1,2 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.alibaba.boot.nacos.discovery.autoconfigure.NacosDiscoveryAutoConfiguration
com.alibaba.boot.nacos.discovery.autoconfigure.NacosDiscoveryAutoConfiguration

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 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.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.annotation.NacosInjected;
@ -64,13 +65,13 @@ public class NacosDiscoveryAutoConfigurationTest {
}
@Test(expected = NoSuchBeanDefinitionException.class)
public void testNacosConfigGlobalBean() {
public void testNacosDiscoveryGlobalBean() {
Assert.assertNull(applicationContext
.getBean(NacosBeanUtils.GLOBAL_NACOS_PROPERTIES_BEAN_NAME));
}
@Test(expected = NoSuchBeanDefinitionException.class)
public void testNacosDiscoveryGlobalBean() {
public void testNacosConfigGlobalBean() {
Assert.assertNull(applicationContext
.getBean(NacosBeanUtils.CONFIG_GLOBAL_NACOS_PROPERTIES_BEAN_NAME));
}
@ -84,4 +85,8 @@ public class NacosDiscoveryAutoConfigurationTest {
properties.getProperty(PropertyKeyConst.SERVER_ADDR));
}
@Test
public void testAddNacosDiscoveryAutoRegister() {
Assert.assertNotNull(applicationContext.getBean(NacosDiscoveryAutoRegister.class));
}
}

View File

@ -18,7 +18,7 @@
<parent>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-parent</artifactId>
<version>0.1.6</version>
<version>${revision}</version>
<relativePath>../nacos-spring-boot-parent</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -34,13 +34,24 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<scope>true</scope>
</dependency>
<!-- Nacos -->
<dependency>
<groupId>com.alibaba.nacos</groupId>
<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>
@ -53,5 +64,10 @@
<artifactId>nacos-spring-boot-base</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-aot</artifactId>
</dependency>
</dependencies>
</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>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-spring-boot-parent</artifactId>
<version>0.1.6</version>
<version>${revision}</version>
<relativePath>../nacos-spring-boot-parent</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -54,7 +54,20 @@
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId>
<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>
<!-- Test Dependencies -->
<dependency>

View File

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

View File

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

View File

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

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"}]
}
]

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