diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 000000000..c607b546c
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,16 @@
+# editorconfig.org
+root = true
+
+[*]
+indent_style = space
+indent_size = 4
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
+
+[{package.json,.travis.yml}]
+indent_size = 2
\ No newline at end of file
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index fae0c624d..ff44f6384 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -18,5 +18,5 @@ Follow this checklist to help us incorporate your contribution quickly and easil
* [ ] Format the pull request title like `[ISSUE #123] Fix UnknownException when host config not exist`. Each commit in the pull request should have a meaningful subject line and body.
* [ ] Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
* [ ] Write necessary unit-test to verify your logic correction, more mock a little better when cross module dependency exist. If the new feature or significant change is committed, please remember to add integration-test in [test module](https://github.com/alibaba/nacos/tree/master/test).
-* [ ] Run `mvn -B clean apache-rat:check findbugs:findbugs` to make sure basic checks pass. Run `mvn clean install -DskipITs` to make sure unit-test pass. Run `mvn clean test-compile failsafe:integration-test` to make sure integration-test pass.
+* [ ] Run `mvn -B clean package apache-rat:check findbugs:findbugs -Dmaven.test.skip=true` to make sure basic checks pass. Run `mvn clean install -DskipITs` to make sure unit-test pass. Run `mvn clean test-compile failsafe:integration-test` to make sure integration-test pass.
diff --git a/.gitignore b/.gitignore
index dbc93482a..b47f59ded 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,8 +5,11 @@
target
.project
.idea
+.vscode
.DS_Store
+.factorypath
/logs
*.iml
node_modules
test/derby.log
+derby.log
diff --git a/.travis.yml b/.travis.yml
index f85f66155..b3a9f6497 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,6 +4,7 @@ notifications:
- xchaos8@126.com
- nacos_dev@linux.alibaba.com
- dev-nacos@googlegroups.com
+ - mw_configcenter@list.alibaba-inc.com
on_success: change
on_failure: always
@@ -24,7 +25,9 @@ before_install:
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then jdk_switcher use "$CUSTOM_JDK"; fi
script:
-
+ - mvn -B clean package apache-rat:check findbugs:findbugs -Dmaven.test.skip=true
+ - mvn -Prelease-nacos clean install -U
+ - mvn clean package -Pit-test
after_success:
- - mvn clean install -Pit-test
+ - mvn clean package -Pit-test
- mvn sonar:sonar -Psonar-apache
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4bee36e01..5169d21d4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,108 @@
+## 0.7.0(Dec, 2018)
+
+* [ #461 ] Registration failed when instance port is set to 0
+* [ #455 ] The console can't change the change code
+* [ #447 ] 集群模式server挂掉一台后,提供方注册失败
+* [ #445 ] 0.6.1控制台创建配置发布提交时,提示信息有问题
+* [ #442 ] Typos in class names and variables.
+* [ #413 ] The console has some uncaught exceptions
+* [ #395 ] nacos surport mysql in the case of stand-alone mode
+* [ #393 ] Support operation of selector on console
+* [ #365 ] NodeJs SDK support
+* [ #362 ] The metadata will lost when online or offline instance through web ui
+* [ #187 ] Provide Label ability for Naming Service into NACOS for complex multi-DC scenario.
+
+## 0.6.1(Dec, 2018)
+
+* [#421] NamingService's serivce name can't use colon(:) in Windows
+* [#432] When packing nacos-core, ${user.home} is replaced in the logback configuration file (nacos.xml)
+
+## 0.6.0(Dec, 2018)
+
+* [#388] Cluster name should be provided in the Instance
+* [#377] Clean up messy code in Naming module
+* [#369] Support instance list persisted on disk
+* [#366] findbugs-maven-plugin version
+* [#362] The metadata will lost when online or offline instance through web ui
+* [#352] Refactoring internationalization Nacos console
+* [#278] Nacos docker img
+* [#243] optimize the efficiency of integration testing, it’s taking too long now
+
+## 0.5.0(Nov, 2018)
+
+* [#148] Naming write performace.
+* [#175] Support deregistering instance automatically.
+* [#176] Naming client query instance method should bypass local cache at client start.
+* [#177] Console supports registering new empty service and delete empty service.
+* [#181] NPE when adding a instance if no leader in the raft cluster.
+* [#193] Configure host domain name cause nacos server cluster is unavailable.
+* [#209] Disable service and cluster level customization in client registerInstance method.
+* [#214] Please support Java 11.
+* [#222] print more nacos server start status info in start.log.
+* [#231] Refactoring: Parsing the Nacos home directory and the cluster.conf file.
+* [#246] "mvn -B clean apache-rat:check findbugs:findbugs" did not work as expected.
+* [#251] Console Editor Optimization.
+* [#254] DataId and group are required in historical version and listener query.
+* [#256] Whether the service discovery data needs to add a newline link symbol.
+* [#257] Listening query switching query dimension data is not refreshed.
+* [#258] Remove the Balloon of DataId/Group.
+* [#259] Listening query paging size problem.
+* [#272] "#it is ip" is also parsed into an instance IP.
+* [#275] nacos coredns plugin to support DNS.
+* [#281] We should lint the console code.
+* [#302] Maven build project supports java 11.
+* [#316] In stand alone mode, Nacos still checks the cluster.conf.
+
+## 0.4.0(Nov 7, 2018)
+
+* [#216] Fix tenant dir problem
+* [#197] Service update ignored some properties
+* [#190] Client beat lose weight info and metadata info
+* [#188] Console delete data cannot be updated in time
+* [#179] Listening query fail when namespace is not blank
+* [#157] Lack information in readme.md to describe the related project repositories for Nacos echosystem
+* [#144] There have a error and something are not clear
+* [#106] Snapshot file create error
+* [#92] Eliminate warnings, refactor code, show start.log detail
+
+
+## 0.3.0(Oct 26, 2018)
+
+* [#171] UI debug errors
+* [#156] Web UI 404 problem
+* [#155] use local resource
+* [#145] nacos-example not found :org.apache.logging.log4j.core.Logger
+* [#142] UI console show Group
+* [#149] Fix naming client beat process failed bug.
+* [#150] Fix naming service registration hangs bug.
+
+## 0.3.0-RC1(Oct 19, 2018)
+
+* [#33] Support console for config management.
+* [#51] Support console for naming service.
+* [#121] Fix get instance method hanging bug.
+* [#138] Add a flag to indicate if instance is offline.
+* [#130] Fix health check disabled if machine has one CPU core bug.
+* [#139] Fix still get instance with zero weight bug.
+* [#128] Fix console layout bug.
+
+
+
+## 0.2.1-release(Sept 28, 2018)
+
+* FIx deregister last instance failed error.
+* Fix url pattern error.
+* Fully integrate with and seamlessly support Spring framework, Spring Boot and Spring Cloud
+* Separate nacos-api from nacos client implementation
+* Support high available cluster mode
+* Fix cluster node health check abnormality
+* Fix stand-alone mode gets the change history list exception
+* Fix Pulling does not exist configuration print io exception
+* Optimized log framework
+* Service Discovery: Client support getting server status.
+* Service Discovery: Client support get all service names of server.
+* Service Discovery: Client support get all subscribed services.
+
## 0.2.0 (Sept 17, 2018)
#### FEATURES:
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..58a6aefc5
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,73 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as
+contributors and maintainers pledge to making participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, gender identity and expression, level of experience,
+education, socio-economic status, nationality, personal appearance, race,
+religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment
+include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or
+ advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic
+ address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable
+behavior and are expected to take appropriate and fair corrective action in
+response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or
+reject comments, commits, code, wiki edits, issues, and other contributions
+that are not aligned to this Code of Conduct, or to ban temporarily or
+permanently any contributor for other behaviors that they deem inappropriate,
+threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community. Examples of
+representing a project or community include using an official project e-mail
+address, posting via an official social media account, or acting as an appointed
+representative at an online or offline event. Representation of a project may be
+further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported by contacting the project team at users-nacos@googlegroups.com. All
+complaints will be reviewed and investigated and will result in a response that
+is deemed necessary and appropriate to the circumstances. The project team is
+obligated to maintain confidentiality with regard to the reporter of an incident.
+Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good
+faith may face temporary or permanent repercussions as determined by other
+members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
+available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
+
+[homepage]: https://www.contributor-covenant.org
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e75d19700..534b50af3 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,31 +1,124 @@
-## How To Contribute
+# Contributing to Nacos
-We are always very happy to have contributions, whether for trivial cleanups or big new features.
-We want to have high quality, well documented codes for each programming language.
+Welcome to Nacos! This document is a guideline about how to contribute to Nacos.
-Nor is code the only way to contribute to the project. We strongly value documentation, integration with other project, and gladly accept improvements for these aspects.
+If you find something incorrect or missing, please leave comments / suggestions.
-## Contributing code
+## Before you get started
-To submit a change for inclusion, please do the following:
+### Code of Conduct
-#### If the change is non-trivial please include some unit tests that cover the new functionality.
-#### If you are introducing a completely new feature or API it is a good idea to start a wiki and get consensus on the basic design first.
-#### It is our job to follow up on patches in a timely fashion. Nag us if we aren't doing our job (sometimes we drop things).
+Please make sure to read and observe our [Code of Conduct](./CODE_OF_CONDUCT.md).
-## Becoming a Committer
+## Contributing
-We are always interested in adding new contributors. What we look for are series of contributions, good taste and ongoing interest in the project. If you are interested in becoming a committer, please let one of the existing committers know and they can help you walk through the process.
+Nacos welcome new participants of any role, including user, contributor, committer and PMC.
-Nowadays,we have several important contribution points:
-#### Wiki & JavaDoc
-#### Nacos Console
-#### Nacos SDK(C++\.Net\Php\Python\Go\Node.js)
+![](http://acm-public.oss-cn-hangzhou.aliyuncs.com/contributor_definition.png)
-##### Prerequisite
-If you want to contribute the above listing points, you must abide our some prerequisites:
-###### Readability - API must have Javadoc,some very important methods also must have javadoc
-###### Testability - 80% above unit test coverage about main process
-###### Maintainability - Comply with our [PMD spec](style/codeStyle.xml), and at least 3 month update frequency
-###### Deployability - We encourage you to deploy into [maven repository](http://search.maven.org/)
+We encourage new comers actively join in Nacos projects and involving from user role to committer role, and even PMC role. In order to accomplish this, new comers needs to actively contribute in Nacos project. The following paragraph introduce how to contribute in Nacos way.
+
+#### Open / pickup an issue for preparation
+
+If you find a typo in document, find a bug in code, or want new features, or want to give suggestions, you can [open an issue on GitHub](https://github.com/alibaba/Nacos/issues/new) to report it.
+
+If you just want to contribute directly you can choose the issue below.
+
+- [Contribution Welcome](https://github.com/alibaba/nacos/labels/contribution%20welcome): Heavily needed issue, but currently short of hand.
+
+- [good first issue](https://github.com/alibaba/nacos/labels/good%20first%20issue): Good for newcomers, new comer can pickup one for warm-up.
+
+
+We strongly value documentation and integration with other projects such as Spring Cloud, Kubernetes, Dubbo, etc. We are very glad to work on any issue for these aspects.
+
+Please note that any PR must be associated with a valid issue. Otherwise the PR will be rejected.
+
+#### Begin your contribute
+
+Now if you want to contribute, please create a new pull request.
+
+We use the `develop` branch as the development branch, which indicates that this is a unstable branch.
+
+Further more, our branching model complies to [https://nvie.com/posts/a-successful-git-branching-model/](https://nvie.com/posts/a-successful-git-branching-model/). We strongly suggest new comers walk through the above article before creating PR.
+
+Now, if you are ready to create PR, here is the workflow for contributors:
+
+1. Fork to your own
+
+2. Clone fork to local repository
+
+3. Create a new branch and work on it
+
+4. Keep your branch in sync
+
+5. Commit your changes (make sure your commit message concise)
+
+6. Push your commits to your forked repository
+
+7. Create a pull request to **develop** branch.
+
+
+When creating pull request:
+
+1. Please follow [the pull request template](./.github/PULL_REQUEST_TEMPLATE.md).
+
+2. Please create the request to **develop** branch.
+
+3. Please make sure the PR has a corresponding issue.
+
+4. If your PR contains large changes, e.g. component refactor or new components, please write detailed documents about its design and usage.
+
+5. Note that a single PR should not be too large. If heavy changes are required, it's better to separate the changes to a few individual PRs.
+
+6. After creating a PR, one or more reviewers will be assigned to the pull request.
+
+7. Before merging a PR, squash any fix review feedback, typo, merged, and rebased sorts of commits. The final commit message should be clear and concise.
+
+
+If your PR contains large changes, e.g. component refactor or new components, please write detailed documents about its design and usage.
+
+### Code review guidance
+
+Committers will rotate reviewing the code to make sure all the PR will be reviewed timely and by at least one committer before merge. If we aren't doing our job (sometimes we drop things). And as always, we welcome volunteers for code review.
+
+Some principles:
+
+- Readability - Important code should be well-documented. API should have Javadoc. Code style should be complied with the existing one.
+
+- Elegance: New functions, classes or components should be well designed.
+
+- Testability - 80% of the new code should be covered by unit test cases.
+
+- Maintainability - Comply with our [PMD spec](style/codeStyle.xml), and 3-month-frequency update should be maintained at least.
+
+
+### Now how about try become a committer?
+
+Generally speaking, contribute 8 non-trivial patches and get at least three different people to review them (you'll need three people to support you). Then ask someone to nominate you. You're demonstrating your:
+
+- at least 8 PR and the associated issues to the project,
+
+- ability to collaborate with the team,
+
+- understanding of the projects' code base and coding style, and
+
+- ability to write good code (last but certainly not least)
+
+
+A current committer nominates you by slacking the team on the Nacos issue with label "nomination"
+
+- your first and last name
+
+- a link to your Git profile
+
+- an explanation of why you should be a committer,
+
+- Elaborate the top 3 PR and the associated issues the nominator has worked with you that can demonstrate your ability.
+
+
+Two other committer need to second your nomination. If no one objects in 5 working days (China), you're a committer. If anyone objects or wants more information, the committers discuss and usually come to a consensus (within the 5 working days). If issues cannot be resolved, there's a vote among current committers.
+
+![](http://acm-public.oss-cn-hangzhou.aliyuncs.com/nomination_process.png)
+
+In the worst case, this can drag out for two weeks. Keep contributing! Even in the rare cases where a nomination fails, the objection is usually something easy to address like "more patches" or "not enough people are familiar with this person's work."
diff --git a/README.md b/README.md
index 69222deb6..8b4c18b15 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,16 @@
-## Nacos
+
+
+# Nacos: Dynamic *Na*ming and *Co*nfiguration *S*ervice
[![Gitter](https://badges.gitter.im/alibaba/nacos.svg)](https://gitter.im/alibaba/nacos?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
[![Gitter](https://travis-ci.org/alibaba/nacos.svg?branch=master)](https://travis-ci.org/alibaba/nacos)
-------
-
-Nacos is an easy-to-use platform designed for dynamic service discovery and configuration and service management. It helps you to build cloud native applications and microservices platform easily.
+
+## What does it do
+
+Nacos (official site: [http://nacos.io](http://nacos.io)) is an easy-to-use platform designed for dynamic service discovery and configuration and service management. It helps you to build cloud native applications and microservices platform easily.
Service is a first-class citizen in Nacos. Nacos supports almost all type of services,for example,[Dubbo/gRPC service](https://nacos.io/en-us/docs/use-nacos-with-dubbo.html)、[Spring Cloud RESTFul service](https://nacos.io/en-us/docs/use-nacos-with-springcloud.html) or [Kubernetes service](https://nacos.io/en-us/docs/use-nacos-with-kubernetes.html).
@@ -29,60 +33,70 @@ Nacos provides four major functions.
Nacos provides an easy-to-use service dashboard to help you manage your services metadata, configuration, kubernetes DNS, service health and metrics statistics.
-### Quick Start
+## Quick Start
It is super easy to get started with your first project.
-1. #### Download run package
-[Download](https://github.com/alibaba/nacos/releases/download/0.2.1/nacos-server-0.2.1.zip)
+#### Step 1: Download the binary package
+You can download the package from the [latest stable release](https://github.com/alibaba/nacos/releases).
+
+Take release nacos-server-0.6.1.zip for example.
```
-unzip nacos-server-0.2.1.zip
+unzip nacos-server-0.6.1.zip
cd nacos/bin
```
-2. #### Start Server
-* ##### Linux/Unix/Mac
+#### Step 2: Start Server
+On the **Linux/Unix/Mac** platform, run the following command to start server with standalone mode:
```
-Run the following command to start (standalone means non-cluster mode):
-
sh startup.sh -m standalone
```
-* ##### Windows
+On the **Windows** platform, run the following command to start server with standalone mode. Alternatively, you can also double-click the startup.cmd to run NacosServer.
```
-Run the following command to start:
-
-cmd startup.cmd
-
-Or double-click the startup.cmd to run NacosServer.
+cmd startup.cmd -m standalone
```
For more details, see [quick-start.](https://nacos.io/en-us/docs/quick-start.html)
-3. #### Quick start for other open-source projects:
+## Quick start for other open-source projects:
+* [Quick start with Nacos command and console](https://nacos.io/en-us/docs/quick-start.html)
-* [quick start with spring cloud](https://nacos.io/en-us/docs/use-nacos-with-springcloud.html)
+* [Quick start with dubbo](https://nacos.io/en-us/docs/use-nacos-with-dubbo.html)
-* [quick start with dubbo](https://nacos.io/en-us/docs/use-nacos-with-dubbo.html)
+* [Quick start with spring cloud](https://nacos.io/en-us/docs/quick-start-spring-cloud.html)
-* [quick start with kubernetes](https://nacos.io/en-us/docs/use-nacos-with-kubernetes.html)
+* [Quick start with kubernetes](https://nacos.io/en-us/docs/use-nacos-with-kubernetes.html)
-* [more...](https://nacos.io/)
-### Documentation
+## Documentation
-You can view full documentation on the Nacos website:
+You can view the full documentation from the [Nacos website](https://nacos.io/en-us/docs/what-is-nacos.html).
-* [nacos.io](https://nacos.io/en-us/docs/what-is-nacos.html)
+All the latest and long-term notice can also be found here from [Github notice issue](https://github.com/alibaba/nacos/labels/notice)
-### Contact
-* #### Gitter-[Nacos Gitter](https://gitter.im/alibaba/nacos)
+## Contributing
-* #### Weibo-[Nacos Weibo](https://weibo.com/u/6574374908)
+Contributors are welcomed to join Nacos project. Please check [CONTRIBUTING](./CONTRIBUTING.md) about how to contribute to this project.
-* #### Segmentfault-[Nacos Segmentfault](https://segmentfault.com/t/nacos)
+## Other Related Project Repositories
-* #### Mailing list-[nacos\_dev@linux.alibaba.com](mailto:nacos_dev@linux.alibaba.com).
+* [nacos-spring-project](https://github.com/nacos-group/nacos-spring-project) provides the integration functionality for Spring.
+* [nacos-group](https://github.com/nacos-group) is the reposity that hosts the eco tools for Nacos, such as SDK, synchronization tool, etc.
+* [spring-cloud-alibaba](https://github.com/spring-cloud-incubator/spring-cloud-alibaba) provides the one-stop solution for application development over Alibaba middleware which includes Nacos.
+## Contact
+
+* [Gitter](https://gitter.im/alibaba/nacos): Nacos's IM tool for community messaging, collaboration and discovery.
+* [Twitter](https://twitter.com/nacos2): Follow along for latest nacos news on Twitter.
+* [Weibo](https://weibo.com/u/6574374908): Follow along for latest nacos news on Weibo (Twitter of China version).
+* [Nacos Segmentfault](https://segmentfault.com/t/nacos): Get latest notice and prompt help from Segmentfault.
+* Email Group:
+ * users-nacos@googlegroups.com: Nacos usage general discussion.
+ * dev-nacos@googlegroups.com: Nacos developer discussion (APIs, feature design, etc).
+ * commits-nacos@googlegroups.com: Commits notice, very high frequency.
+* Join us from wechat. Welcome words: Nacos.
+
+![cwex](http://acm-public.oss-cn-hangzhou.aliyuncs.com/xuc.png)
diff --git a/REPORTING-BUGS.md b/REPORTING-BUGS.md
index df2fe10af..e8e075430 100644
--- a/REPORTING-BUGS.md
+++ b/REPORTING-BUGS.md
@@ -21,7 +21,7 @@ We might ask for further information to locate a bug. A duplicated bug report wi
# 如何提交错误报告
-如果Nacos项目的任何部分存在问题或文档问题,请通过[opening an issue][Nacos-issue]告诉我们。我们非常认真地对待错误和错误,在产品面前没有不重要的问题。不过在创建错误报告之前,请检查是否存在报告相同问题的issues。
+如果Nacos项目的任何部分存在问题或文档问题,请通过[opening an issue][Nacos-issue]告诉我们。我们非常认真地对待错误和缺陷,在产品面前没有不重要的问题。不过在创建错误报告之前,请检查是否存在报告相同问题的issues。
为了使错误报告准确且易于理解,请尝试创建以下错误报告:
@@ -36,4 +36,4 @@ We might ask for further information to locate a bug. A duplicated bug report wi
我们可能会要求您提供更多信息以查找错误。将关闭重复的错误报告。
[etcd-issue]:https://github.com/etcd-io/etcd/issues/new
-[filing-good-bugs]:http://fantasai.inkedblade.net/style/talks/filing-good-bugs/
\ No newline at end of file
+[filing-good-bugs]:http://fantasai.inkedblade.net/style/talks/filing-good-bugs/
diff --git a/api/pom.xml b/api/pom.xml
index 6bec84582..05dfc4dce 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -12,30 +12,55 @@
limitations under the License.
-->
-
- com.alibaba.nacos
- nacos-all
- 0.2.1
-
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ com.alibaba.nacos
+ nacos-all
+ 0.7.0
+
- 4.0.0
+ 4.0.0
- nacos-api
- jar
+ nacos-api
+ jar
- nacos-api ${project.version}
- http://maven.apache.org
+ nacos-api ${project.version}
+ http://maven.apache.org
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ 7
+
+
+
+
-
- UTF-8
-
-
-
-
- com.alibaba
- fastjson
-
-
+
+ UTF-8
+
+
+
+ com.alibaba
+ fastjson
+
+
+ org.apache.commons
+ commons-lang3
+
+
+ junit
+ junit
+ test
+
+
+ org.springframework
+ spring-test
+ test
+
+
diff --git a/api/src/main/java/com/alibaba/nacos/api/NacosFactory.java b/api/src/main/java/com/alibaba/nacos/api/NacosFactory.java
index ae8e75e00..6020468cd 100644
--- a/api/src/main/java/com/alibaba/nacos/api/NacosFactory.java
+++ b/api/src/main/java/com/alibaba/nacos/api/NacosFactory.java
@@ -31,7 +31,7 @@ import com.alibaba.nacos.api.naming.NamingService;
public class NacosFactory {
/**
- * create config service
+ * Create config service
*
* @param properties init param
* @return config
@@ -42,7 +42,7 @@ public class NacosFactory {
}
/**
- * create config service
+ * Create config service
*
* @param serverAddr server list
* @return config
@@ -53,7 +53,7 @@ public class NacosFactory {
}
/**
- * create naming service
+ * Create naming service
*
* @param serverAddr server list
* @return Naming
@@ -64,7 +64,7 @@ public class NacosFactory {
}
/**
- * create naming service
+ * Create naming service
*
* @param properties init param
* @return Naming
diff --git a/api/src/main/java/com/alibaba/nacos/api/PropertyKeyConst.java b/api/src/main/java/com/alibaba/nacos/api/PropertyKeyConst.java
index 91c97707b..03941b0c9 100644
--- a/api/src/main/java/com/alibaba/nacos/api/PropertyKeyConst.java
+++ b/api/src/main/java/com/alibaba/nacos/api/PropertyKeyConst.java
@@ -38,4 +38,6 @@ public class PropertyKeyConst {
public final static String ENCODE = "encode";
+ public final static String NAMING_LOAD_CACHE_AT_START = "namingLoadCacheAtStart";
+
}
diff --git a/api/src/main/java/com/alibaba/nacos/api/annotation/NacosInjected.java b/api/src/main/java/com/alibaba/nacos/api/annotation/NacosInjected.java
index ac8ec7765..ba9d636bc 100644
--- a/api/src/main/java/com/alibaba/nacos/api/annotation/NacosInjected.java
+++ b/api/src/main/java/com/alibaba/nacos/api/annotation/NacosInjected.java
@@ -1,12 +1,11 @@
/*
- * 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
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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
+ *
+ * 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,
diff --git a/api/src/main/java/com/alibaba/nacos/api/annotation/NacosProperties.java b/api/src/main/java/com/alibaba/nacos/api/annotation/NacosProperties.java
index fad6d66aa..a6bd2ad6d 100644
--- a/api/src/main/java/com/alibaba/nacos/api/annotation/NacosProperties.java
+++ b/api/src/main/java/com/alibaba/nacos/api/annotation/NacosProperties.java
@@ -1,12 +1,11 @@
/*
- * 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
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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
+ *
+ * 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,
diff --git a/core/src/test/java/com/alibaba/nacos/core/AppTest.java b/api/src/main/java/com/alibaba/nacos/api/cmdb/pojo/Entity.java
similarity index 50%
rename from core/src/test/java/com/alibaba/nacos/core/AppTest.java
rename to api/src/main/java/com/alibaba/nacos/api/cmdb/pojo/Entity.java
index 60c39f223..6124839b2 100644
--- a/core/src/test/java/com/alibaba/nacos/core/AppTest.java
+++ b/api/src/main/java/com/alibaba/nacos/api/cmdb/pojo/Entity.java
@@ -13,41 +13,40 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.alibaba.nacos.core;
+package com.alibaba.nacos.api.cmdb.pojo;
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
+import java.util.Map;
/**
- * Unit test for simple App.
+ * @author nkorange
*/
-public class AppTest
- extends TestCase
-{
- /**
- * Create the test case
- *
- * @param testName name of the test case
- */
- public AppTest( String testName )
- {
- super( testName );
+public class Entity {
+
+ private String type;
+ private String name;
+ private Map labels;
+
+ public String getType() {
+ return type;
}
- /**
- * @return the suite of tests being tested
- */
- public static Test suite()
- {
- return new TestSuite( AppTest.class );
+ public void setType(String type) {
+ this.type = type;
}
- /**
- * Rigourous Test :-)
- */
- public void testApp()
- {
- assertTrue( true );
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Map getLabels() {
+ return labels;
+ }
+
+ public void setLabels(Map labels) {
+ this.labels = labels;
}
}
diff --git a/api/src/main/java/com/alibaba/nacos/api/cmdb/pojo/EntityEvent.java b/api/src/main/java/com/alibaba/nacos/api/cmdb/pojo/EntityEvent.java
new file mode 100644
index 000000000..a51314ba4
--- /dev/null
+++ b/api/src/main/java/com/alibaba/nacos/api/cmdb/pojo/EntityEvent.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * 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
+ *
+ * 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.nacos.api.cmdb.pojo;
+
+/**
+ * @author nkorange
+ */
+public class EntityEvent {
+
+ private EntityEventType type;
+ private String entityName;
+ private String entityType;
+
+ public EntityEventType getType() {
+ return type;
+ }
+
+ public void setType(EntityEventType type) {
+ this.type = type;
+ }
+
+ public String getEntityName() {
+ return entityName;
+ }
+
+ public void setEntityName(String entityName) {
+ this.entityName = entityName;
+ }
+
+ public String getEntityType() {
+ return entityType;
+ }
+
+ public void setEntityType(String entityType) {
+ this.entityType = entityType;
+ }
+}
diff --git a/api/src/main/java/com/alibaba/nacos/api/cmdb/pojo/EntityEventType.java b/api/src/main/java/com/alibaba/nacos/api/cmdb/pojo/EntityEventType.java
new file mode 100644
index 000000000..5ad6dfac5
--- /dev/null
+++ b/api/src/main/java/com/alibaba/nacos/api/cmdb/pojo/EntityEventType.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * 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
+ *
+ * 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.nacos.api.cmdb.pojo;
+
+/**
+ * @author nkorange
+ */
+public enum EntityEventType {
+ /**
+ *
+ */
+ ENTITY_ADD_OR_UPDATE,
+ /**
+ *
+ */
+ ENTITY_REMOVE
+}
diff --git a/api/src/main/java/com/alibaba/nacos/api/cmdb/pojo/Label.java b/api/src/main/java/com/alibaba/nacos/api/cmdb/pojo/Label.java
new file mode 100644
index 000000000..45883e6c3
--- /dev/null
+++ b/api/src/main/java/com/alibaba/nacos/api/cmdb/pojo/Label.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * 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
+ *
+ * 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.nacos.api.cmdb.pojo;
+
+import java.util.Set;
+
+/**
+ * @author nkorange
+ */
+public class Label {
+
+ private String name;
+ private Set values;
+ private String description;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Set getValues() {
+ return values;
+ }
+
+ public void setValues(Set values) {
+ this.values = values;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+}
diff --git a/api/src/main/java/com/alibaba/nacos/api/cmdb/pojo/PreservedEntityTypes.java b/api/src/main/java/com/alibaba/nacos/api/cmdb/pojo/PreservedEntityTypes.java
new file mode 100644
index 000000000..b48729cdc
--- /dev/null
+++ b/api/src/main/java/com/alibaba/nacos/api/cmdb/pojo/PreservedEntityTypes.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * 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
+ *
+ * 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.nacos.api.cmdb.pojo;
+
+/**
+ * @author nkorange
+ */
+public enum PreservedEntityTypes {
+ /**
+ * Ip
+ */
+ ip,
+ /**
+ * Service
+ */
+ service
+}
diff --git a/api/src/main/java/com/alibaba/nacos/api/cmdb/spi/CmdbService.java b/api/src/main/java/com/alibaba/nacos/api/cmdb/spi/CmdbService.java
new file mode 100644
index 000000000..eadee776f
--- /dev/null
+++ b/api/src/main/java/com/alibaba/nacos/api/cmdb/spi/CmdbService.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * 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
+ *
+ * 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.nacos.api.cmdb.spi;
+
+import com.alibaba.nacos.api.cmdb.pojo.Entity;
+import com.alibaba.nacos.api.cmdb.pojo.EntityEvent;
+import com.alibaba.nacos.api.cmdb.pojo.Label;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Service to visit CMDB store
+ *
+ * @author nkorange
+ */
+public interface CmdbService {
+
+ /**
+ * Get all label names stored in CMDB
+ *
+ * @return label name set
+ */
+ Set getLabelNames();
+
+ /**
+ * Get all possible entity types in CMDB
+ *
+ * @return all entity types
+ */
+ Set getEntityTypes();
+
+ /**
+ * Get label info
+ *
+ * @param labelName label name
+ * @return label info
+ */
+ Label getLabel(String labelName);
+
+ /**
+ * Get label value of label name of ip
+ *
+ * @param entityName entity name
+ * @param entityType entity type
+ * @param labelName target label name
+ * @return label value
+ */
+ String getLabelValue(String entityName, String entityType, String labelName);
+
+ /**
+ * Get all label value of ip
+ *
+ * @param entityName entity name
+ * @param entityType entity type
+ * @return all label values
+ */
+ Map getLabelValues(String entityName, String entityType);
+
+ /**
+ * Dump all entities in CMDB
+ *
+ * @return all entities
+ */
+ Map> getAllEntities();
+
+ /**
+ * get label change events
+ *
+ * @param timestamp start time of generated events
+ * @return label events
+ */
+ List getEntityEvents(long timestamp);
+
+ /**
+ * Get single entity
+ *
+ * @param entityName name of entity
+ * @param entityType type of entity
+ * @return
+ */
+ Entity getEntity(String entityName, String entityType);
+}
diff --git a/api/src/main/java/com/alibaba/nacos/api/common/Constants.java b/api/src/main/java/com/alibaba/nacos/api/common/Constants.java
index ba40dbf74..130fe7d5d 100644
--- a/api/src/main/java/com/alibaba/nacos/api/common/Constants.java
+++ b/api/src/main/java/com/alibaba/nacos/api/common/Constants.java
@@ -85,11 +85,6 @@ public class Constants {
*/
public static final int ONCE_TIMEOUT = 2000;
- /**
- * millisecond
- */
- public static final int CONN_TIMEOUT = 2000;
-
/**
* millisecond
*/
@@ -110,9 +105,9 @@ public class Constants {
public static final int FLOW_CONTROL_INTERVAL = 1000;
- public static final String LINE_SEPARATOR = Character.toString((char) 1);
+ public static final String LINE_SEPARATOR = Character.toString((char)1);
- public static final String WORD_SEPARATOR = Character.toString((char) 2);
+ public static final String WORD_SEPARATOR = Character.toString((char)2);
public static final String LONGPULLING_LINE_SEPARATOR = "\r\n";
@@ -124,4 +119,7 @@ public class Constants {
public static final String NAMING_INSTANCE_ID_SPLITTER = "#";
public static final int NAMING_INSTANCE_ID_SEG_COUNT = 4;
+ public static final String NAMING_HTTP_HEADER_SPILIER = "\\|";
+
+ public static final String NAMING_DEFAULT_CLUSTER_NAME = "DEFAULT";
}
diff --git a/api/src/main/java/com/alibaba/nacos/api/config/ConfigFactory.java b/api/src/main/java/com/alibaba/nacos/api/config/ConfigFactory.java
index 298705c70..52179b112 100644
--- a/api/src/main/java/com/alibaba/nacos/api/config/ConfigFactory.java
+++ b/api/src/main/java/com/alibaba/nacos/api/config/ConfigFactory.java
@@ -29,7 +29,7 @@ import com.alibaba.nacos.api.exception.NacosException;
public class ConfigFactory {
/**
- * create config service
+ * Create Config
*
* @param properties init param
* @return ConfigService
@@ -47,11 +47,11 @@ public class ConfigFactory {
}
/**
- * create config service
+ * Create Config
*
- * @param serverAddr serverlist
- * @return ConfigService
- * @throws NacosException Exception
+ * @param serverAddr serverList
+ * @return Config
+ * @throws ConfigService Exception
*/
public static ConfigService createConfigService(String serverAddr) throws NacosException {
Properties properties = new Properties();
diff --git a/api/src/main/java/com/alibaba/nacos/api/config/ConfigService.java b/api/src/main/java/com/alibaba/nacos/api/config/ConfigService.java
index 07743b0bf..3e79f950c 100644
--- a/api/src/main/java/com/alibaba/nacos/api/config/ConfigService.java
+++ b/api/src/main/java/com/alibaba/nacos/api/config/ConfigService.java
@@ -26,7 +26,7 @@ import com.alibaba.nacos.api.exception.NacosException;
public interface ConfigService {
/**
- * get config
+ * Get config
*
* @param dataId dataId
* @param group group
@@ -52,7 +52,7 @@ public interface ConfigService {
void addListener(String dataId, String group, Listener listener) throws NacosException;
/**
- * publish config.
+ * Publish config.
*
* @param dataId dataId
* @param group group
@@ -63,7 +63,7 @@ public interface ConfigService {
boolean publishConfig(String dataId, String group, String content) throws NacosException;
/**
- * remove config
+ * Remove config
*
* @param dataId dataId
* @param group group
@@ -73,7 +73,7 @@ public interface ConfigService {
boolean removeConfig(String dataId, String group) throws NacosException;
/**
- * remove listener
+ * Remove listener
*
* @param dataId dataId
* @param group group
@@ -82,7 +82,7 @@ public interface ConfigService {
void removeListener(String dataId, String group, Listener listener);
/**
- * get server status
+ * Get server status
*
* @return whether health
*/
diff --git a/api/src/main/java/com/alibaba/nacos/api/config/annotation/NacosConfigListener.java b/api/src/main/java/com/alibaba/nacos/api/config/annotation/NacosConfigListener.java
index aad64b87a..dfc490385 100644
--- a/api/src/main/java/com/alibaba/nacos/api/config/annotation/NacosConfigListener.java
+++ b/api/src/main/java/com/alibaba/nacos/api/config/annotation/NacosConfigListener.java
@@ -1,12 +1,11 @@
/*
- * 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
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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
+ *
+ * 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,
@@ -57,8 +56,7 @@ public @interface NacosConfigListener {
Class extends NacosConfigConverter> converter() default NacosConfigConverter.class;
/**
- * The {@link NacosProperties} attribute, If not specified, it will use
- * global Nacos Properties.
+ * The {@link NacosProperties} attribute, If not specified, it will use global Nacos Properties.
*
* @return the default value is {@link NacosProperties}
*/
diff --git a/api/src/main/java/com/alibaba/nacos/api/config/annotation/NacosConfigurationProperties.java b/api/src/main/java/com/alibaba/nacos/api/config/annotation/NacosConfigurationProperties.java
index 2cd57f19b..2eedfeb93 100644
--- a/api/src/main/java/com/alibaba/nacos/api/config/annotation/NacosConfigurationProperties.java
+++ b/api/src/main/java/com/alibaba/nacos/api/config/annotation/NacosConfigurationProperties.java
@@ -1,12 +1,11 @@
/*
- * 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
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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
+ *
+ * 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,
@@ -24,7 +23,6 @@ import java.lang.annotation.*;
import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
-
/**
* An annotation for Nacos configuration Properties for binding POJO as Properties Object.
*
@@ -52,51 +50,46 @@ public @interface NacosConfigurationProperties {
String dataId();
/**
- * It indicates the properties of current doBind bean is auto-refreshed
- * when Nacos configuration is changed.
+ * It indicates the properties of current doBind bean is auto-refreshed when Nacos configuration is changed.
*
* @return default value is false
*/
boolean autoRefreshed() default false;
-
/**
- * Flag to indicate that when binding to this object invalid fields should be ignored.
- * Invalid means invalid according to the binder that is used, and usually this means
- * fields of the wrong type (or that cannot be coerced into the correct type).
+ * Flag to indicate that when binding to this object invalid fields should be ignored. Invalid means invalid
+ * according to the binder that is used, and usually this means fields of the wrong type (or that cannot be coerced
+ * into the correct type).
*
* @return the flag value (default false)
*/
boolean ignoreInvalidFields() default false;
/**
- * Flag to indicate that when binding to this object fields with periods in their
- * names should be ignored.
+ * Flag to indicate that when binding to this object fields with periods in their names should be ignored.
*
* @return the flag value (default false)
*/
boolean ignoreNestedProperties() default false;
/**
- * Flag to indicate that when binding to this object unknown fields should be ignored.
- * An unknown field could be a sign of a mistake in the Properties.
+ * Flag to indicate that when binding to this object unknown fields should be ignored. An unknown field could be a
+ * sign of a mistake in the Properties.
*
* @return the flag value (default true)
*/
boolean ignoreUnknownFields() default true;
/**
- * Flag to indicate that an exception should be raised if a Validator is available and
- * validation fails. If it is set to false, validation errors will be swallowed. They
- * will be logged, but not propagated to the caller.
+ * Flag to indicate that an exception should be raised if a Validator is available and validation fails. If it is
+ * set to false, validation errors will be swallowed. They will be logged, but not propagated to the caller.
*
* @return the flag value (default true)
*/
boolean exceptionIfInvalid() default true;
/**
- * The {@link NacosProperties} attribute, If not specified, it will use
- * global Nacos Properties.
+ * The {@link NacosProperties} attribute, If not specified, it will use global Nacos Properties.
*
* @return the default value is {@link NacosProperties}
*/
diff --git a/api/src/main/java/com/alibaba/nacos/api/config/annotation/NacosIgnore.java b/api/src/main/java/com/alibaba/nacos/api/config/annotation/NacosIgnore.java
index 99d65c98b..6d3ce0399 100644
--- a/api/src/main/java/com/alibaba/nacos/api/config/annotation/NacosIgnore.java
+++ b/api/src/main/java/com/alibaba/nacos/api/config/annotation/NacosIgnore.java
@@ -1,12 +1,11 @@
/*
- * 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
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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
+ *
+ * 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,
@@ -19,8 +18,7 @@ package com.alibaba.nacos.api.config.annotation;
import java.lang.annotation.*;
/**
- * An annotation for ignore field from annotated
- * {@link NacosConfigurationProperties} Properties Object.
+ * An annotation for ignore field from annotated {@link NacosConfigurationProperties} Properties Object.
*
* @author Mercy
* @see NacosConfigurationProperties
diff --git a/api/src/main/java/com/alibaba/nacos/api/config/annotation/NacosProperty.java b/api/src/main/java/com/alibaba/nacos/api/config/annotation/NacosProperty.java
index 2be36cbd8..80aa3c661 100644
--- a/api/src/main/java/com/alibaba/nacos/api/config/annotation/NacosProperty.java
+++ b/api/src/main/java/com/alibaba/nacos/api/config/annotation/NacosProperty.java
@@ -1,12 +1,11 @@
/*
- * 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
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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
+ *
+ * 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,
@@ -19,9 +18,8 @@ package com.alibaba.nacos.api.config.annotation;
import java.lang.annotation.*;
/**
- * An annotation for Nacos Property name of Nacos Configuration to
- * bind a field from annotated {@link NacosConfigurationProperties}
- * Properties Object.
+ * An annotation for Nacos Property name of Nacos Configuration to bind a field from annotated {@link
+ * NacosConfigurationProperties} Properties Object.
*
* @author Mercy
* @see NacosConfigurationProperties
diff --git a/api/src/main/java/com/alibaba/nacos/api/config/annotation/NacosValue.java b/api/src/main/java/com/alibaba/nacos/api/config/annotation/NacosValue.java
index b9dbdbd6f..a77ac669e 100644
--- a/api/src/main/java/com/alibaba/nacos/api/config/annotation/NacosValue.java
+++ b/api/src/main/java/com/alibaba/nacos/api/config/annotation/NacosValue.java
@@ -1,12 +1,11 @@
/*
- * 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
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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
+ *
+ * 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,
diff --git a/api/src/main/java/com/alibaba/nacos/api/config/convert/NacosConfigConverter.java b/api/src/main/java/com/alibaba/nacos/api/config/convert/NacosConfigConverter.java
index fc0cb216e..d3e3702b2 100644
--- a/api/src/main/java/com/alibaba/nacos/api/config/convert/NacosConfigConverter.java
+++ b/api/src/main/java/com/alibaba/nacos/api/config/convert/NacosConfigConverter.java
@@ -1,12 +1,11 @@
/*
- * 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
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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
+ *
+ * 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,
@@ -41,5 +40,4 @@ public interface NacosConfigConverter {
*/
T convert(String config);
-
}
diff --git a/api/src/main/java/com/alibaba/nacos/api/config/filter/IConfigContext.java b/api/src/main/java/com/alibaba/nacos/api/config/filter/IConfigContext.java
index 63ab4d2ff..5b9d638a2 100644
--- a/api/src/main/java/com/alibaba/nacos/api/config/filter/IConfigContext.java
+++ b/api/src/main/java/com/alibaba/nacos/api/config/filter/IConfigContext.java
@@ -22,7 +22,7 @@ package com.alibaba.nacos.api.config.filter;
*/
public interface IConfigContext {
/**
- * get context param by key
+ * Get context param by key
*
* @param key
* @return context
@@ -30,7 +30,7 @@ public interface IConfigContext {
Object getParameter(String key);
/**
- * set context param
+ * Set context param
*
* @param key key
* @param value value
diff --git a/api/src/main/java/com/alibaba/nacos/api/config/filter/IConfigFilter.java b/api/src/main/java/com/alibaba/nacos/api/config/filter/IConfigFilter.java
index c4217418a..8e7b2ba2e 100644
--- a/api/src/main/java/com/alibaba/nacos/api/config/filter/IConfigFilter.java
+++ b/api/src/main/java/com/alibaba/nacos/api/config/filter/IConfigFilter.java
@@ -24,7 +24,7 @@ import com.alibaba.nacos.api.exception.NacosException;
*/
public interface IConfigFilter {
/**
- * init
+ * Init
*
* @param filterConfig Filter Config
*/
@@ -47,14 +47,14 @@ public interface IConfigFilter {
void deploy();
/**
- * get order
+ * Get order
*
* @return order number
*/
int getOrder();
/**
- * get filterName
+ * Get filterName
*
* @return filter name
*/
diff --git a/api/src/main/java/com/alibaba/nacos/api/config/filter/IConfigFilterChain.java b/api/src/main/java/com/alibaba/nacos/api/config/filter/IConfigFilterChain.java
index 8f7a764da..fa97dcfab 100644
--- a/api/src/main/java/com/alibaba/nacos/api/config/filter/IConfigFilterChain.java
+++ b/api/src/main/java/com/alibaba/nacos/api/config/filter/IConfigFilterChain.java
@@ -24,7 +24,7 @@ import com.alibaba.nacos.api.exception.NacosException;
*/
public interface IConfigFilterChain {
/**
- * filter aciton
+ * Filter aciton
*
* @param request request
* @param response response
diff --git a/api/src/main/java/com/alibaba/nacos/api/config/filter/IConfigResponse.java b/api/src/main/java/com/alibaba/nacos/api/config/filter/IConfigResponse.java
index b08e9946c..c792f8db8 100644
--- a/api/src/main/java/com/alibaba/nacos/api/config/filter/IConfigResponse.java
+++ b/api/src/main/java/com/alibaba/nacos/api/config/filter/IConfigResponse.java
@@ -30,7 +30,7 @@ public interface IConfigResponse {
Object getParameter(String key);
/**
- * get config context
+ * Get config context
*
* @return configContext
*/
diff --git a/api/src/main/java/com/alibaba/nacos/api/config/filter/IFilterConfig.java b/api/src/main/java/com/alibaba/nacos/api/config/filter/IFilterConfig.java
index 26ba4508e..bea4f9a4c 100644
--- a/api/src/main/java/com/alibaba/nacos/api/config/filter/IFilterConfig.java
+++ b/api/src/main/java/com/alibaba/nacos/api/config/filter/IFilterConfig.java
@@ -30,7 +30,7 @@ public interface IFilterConfig {
String getFilterName();
/**
- * get init param
+ * Get init param
*
* @param name
* @return param
diff --git a/api/src/main/java/com/alibaba/nacos/api/config/listener/AbstractListener.java b/api/src/main/java/com/alibaba/nacos/api/config/listener/AbstractListener.java
index c9d8af5e6..f0f874a2b 100644
--- a/api/src/main/java/com/alibaba/nacos/api/config/listener/AbstractListener.java
+++ b/api/src/main/java/com/alibaba/nacos/api/config/listener/AbstractListener.java
@@ -26,7 +26,7 @@ import java.util.concurrent.Executor;
public abstract class AbstractListener implements Listener {
/**
- * use default executor
+ * Use default executor
*/
@Override
public Executor getExecutor() {
diff --git a/api/src/main/java/com/alibaba/nacos/api/config/listener/Listener.java b/api/src/main/java/com/alibaba/nacos/api/config/listener/Listener.java
index 5e8ca457a..501168a3f 100644
--- a/api/src/main/java/com/alibaba/nacos/api/config/listener/Listener.java
+++ b/api/src/main/java/com/alibaba/nacos/api/config/listener/Listener.java
@@ -17,7 +17,6 @@ package com.alibaba.nacos.api.config.listener;
import java.util.concurrent.Executor;
-
/**
* Listener for watch config
*
@@ -26,15 +25,14 @@ import java.util.concurrent.Executor;
public interface Listener {
/**
- * get executor for execute this receive
+ * Get executor for execute this receive
*
* @return Executor
*/
Executor getExecutor();
-
/**
- * receive config info
+ * Receive config info
*
* @param configInfo config info
*/
diff --git a/api/src/main/java/com/alibaba/nacos/api/exception/NacosException.java b/api/src/main/java/com/alibaba/nacos/api/exception/NacosException.java
index 1d10dd753..7806e9635 100644
--- a/api/src/main/java/com/alibaba/nacos/api/exception/NacosException.java
+++ b/api/src/main/java/com/alibaba/nacos/api/exception/NacosException.java
@@ -75,7 +75,6 @@ public class NacosException extends Exception {
*/
public static final int CLIENT_OVER_THRESHOLD = -503;
-
/**
* server error code
* 400 403 throw exception to user
@@ -107,5 +106,4 @@ public class NacosException extends Exception {
*/
public static final int OVER_THRESHOLD = 503;
-
}
diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/NamingFactory.java b/api/src/main/java/com/alibaba/nacos/api/naming/NamingFactory.java
index d554bbd06..d018eca02 100644
--- a/api/src/main/java/com/alibaba/nacos/api/naming/NamingFactory.java
+++ b/api/src/main/java/com/alibaba/nacos/api/naming/NamingFactory.java
@@ -27,25 +27,25 @@ import com.alibaba.nacos.api.exception.NacosException;
*/
public class NamingFactory {
- public static NamingService createNamingService(String serverList) throws NacosException {
- try {
- Class> driverImplClass = Class.forName("com.alibaba.nacos.client.naming.NacosNamingService");
- Constructor constructor = driverImplClass.getConstructor(String.class);
- NamingService vendorImpl = (NamingService) constructor.newInstance(serverList);
- return vendorImpl;
- } catch (Throwable e) {
- throw new NacosException(-400, e.getMessage());
- }
- }
+ public static NamingService createNamingService(String serverList) throws NacosException {
+ try {
+ Class> driverImplClass = Class.forName("com.alibaba.nacos.client.naming.NacosNamingService");
+ Constructor constructor = driverImplClass.getConstructor(String.class);
+ NamingService vendorImpl = (NamingService)constructor.newInstance(serverList);
+ return vendorImpl;
+ } catch (Throwable e) {
+ throw new NacosException(-400, e.getMessage());
+ }
+ }
- public static NamingService createNamingService(Properties properties) throws NacosException {
- try {
- Class> driverImplClass = Class.forName("com.alibaba.nacos.client.naming.NacosNamingService");
- Constructor constructor = driverImplClass.getConstructor(Properties.class);
- NamingService vendorImpl = (NamingService) constructor.newInstance(properties);
- return vendorImpl;
- } catch (Throwable e) {
- throw new NacosException(-400, e.getMessage());
- }
- }
+ public static NamingService createNamingService(Properties properties) throws NacosException {
+ try {
+ Class> driverImplClass = Class.forName("com.alibaba.nacos.client.naming.NacosNamingService");
+ Constructor constructor = driverImplClass.getConstructor(Properties.class);
+ NamingService vendorImpl = (NamingService)constructor.newInstance(properties);
+ return vendorImpl;
+ } catch (Throwable e) {
+ throw new NacosException(-400, e.getMessage());
+ }
+ }
}
diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/NamingService.java b/api/src/main/java/com/alibaba/nacos/api/naming/NamingService.java
index 1ece5c4ad..02622d8df 100644
--- a/api/src/main/java/com/alibaba/nacos/api/naming/NamingService.java
+++ b/api/src/main/java/com/alibaba/nacos/api/naming/NamingService.java
@@ -20,6 +20,7 @@ import com.alibaba.nacos.api.naming.listener.EventListener;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ListView;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
+import com.alibaba.nacos.api.selector.AbstractSelector;
import java.util.List;
@@ -189,7 +190,22 @@ public interface NamingService {
ListView getServicesOfServer(int pageNo, int pageSize) throws NacosException;
/**
+<<<<<<< HEAD
* get all subscribed services of current client
+=======
+ * Get all service names from server
+ *
+ * @param pageNo page index
+ * @param pageSize page size
+ * @param selector selector to filter the resource
+ * @return list of service names
+ * @throws NacosException
+ */
+ ListView getServicesOfServer(int pageNo, int pageSize, AbstractSelector selector) throws NacosException;
+
+ /**
+ * Get all subscribed services of current client
+>>>>>>> upstream/develop
*
* @return subscribed services
* @throws NacosException
diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/AbstractHealthChecker.java b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/AbstractHealthChecker.java
index 583a5b2f0..af71be548 100644
--- a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/AbstractHealthChecker.java
+++ b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/AbstractHealthChecker.java
@@ -15,10 +15,17 @@
*/
package com.alibaba.nacos.api.naming.pojo;
+import com.alibaba.fastjson.annotation.JSONField;
+import com.alibaba.nacos.api.common.Constants;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Objects;
/**
- * @author dungu.zpf
+ * @author nkorange
*/
public abstract class AbstractHealthChecker implements Cloneable {
@@ -32,6 +39,14 @@ public abstract class AbstractHealthChecker implements Cloneable {
this.type = type;
}
+ /**
+ * Clone all fields of this instance to another one
+ *
+ * @return Another instance with exactly the same fields.
+ * @throws CloneNotSupportedException
+ */
+ public abstract AbstractHealthChecker clone() throws CloneNotSupportedException;
+
public static class Http extends AbstractHealthChecker {
public static final String TYPE = "HTTP";
@@ -68,6 +83,25 @@ public abstract class AbstractHealthChecker implements Cloneable {
this.headers = headers;
}
+ @JSONField(serialize = false)
+ public Map getCustomHeaders() {
+ if (StringUtils.isBlank(headers)) {
+ return Collections.emptyMap();
+ }
+
+ Map headerMap = new HashMap(16);
+ for (String s : headers.split(Constants.NAMING_HTTP_HEADER_SPILIER)) {
+ String[] splits = s.split(":");
+ if (splits.length != 2) {
+ continue;
+ }
+
+ headerMap.put(StringUtils.trim(splits[0]), StringUtils.trim(splits[1]));
+ }
+
+ return headerMap;
+ }
+
@Override
public int hashCode() {
return Objects.hash(path, headers, expectedResponseCode);
@@ -79,7 +113,7 @@ public abstract class AbstractHealthChecker implements Cloneable {
return false;
}
- Http other = (Http) obj;
+ Http other = (Http)obj;
if (!strEquals(type, other.getType())) {
return false;
@@ -93,6 +127,18 @@ public abstract class AbstractHealthChecker implements Cloneable {
}
return expectedResponseCode == other.getExpectedResponseCode();
}
+
+ @Override
+ public Http clone() throws CloneNotSupportedException {
+ Http config = new Http();
+
+ config.setPath(this.getPath());
+ config.setHeaders(this.getHeaders());
+ config.setType(this.getType());
+ config.setExpectedResponseCode(this.getExpectedResponseCode());
+
+ return config;
+ }
}
public static class Tcp extends AbstractHealthChecker {
@@ -112,6 +158,12 @@ public abstract class AbstractHealthChecker implements Cloneable {
return obj instanceof Tcp;
}
+
+ public Tcp clone() throws CloneNotSupportedException {
+ Tcp config = new Tcp();
+ config.setType(this.type);
+ return config;
+ }
}
public static class Mysql extends AbstractHealthChecker {
@@ -160,7 +212,7 @@ public abstract class AbstractHealthChecker implements Cloneable {
return false;
}
- Mysql other = (Mysql) obj;
+ Mysql other = (Mysql)obj;
if (!strEquals(user, other.getUser())) {
return false;
@@ -173,6 +225,17 @@ public abstract class AbstractHealthChecker implements Cloneable {
return strEquals(cmd, other.getCmd());
}
+
+ @Override
+ public Mysql clone() throws CloneNotSupportedException {
+ Mysql config = new Mysql();
+ config.setUser(this.getUser());
+ config.setPwd(this.getPwd());
+ config.setCmd(this.getCmd());
+ config.setType(this.getType());
+
+ return config;
+ }
}
private static boolean strEquals(String str1, String str2) {
diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Cluster.java b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Cluster.java
index 287975fab..e4ec09ccd 100644
--- a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Cluster.java
+++ b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Cluster.java
@@ -19,6 +19,7 @@ import java.util.HashMap;
import java.util.Map;
/**
+<<<<<<< HEAD
*
*
* @author dungu.zpf
@@ -33,7 +34,7 @@ public class Cluster {
/**
* Name of cluster
*/
- private String name = "";
+ private String name;
/**
* Health check config of this cluster
@@ -55,7 +56,6 @@ public class Cluster {
*/
private boolean useIPPort4Check = true;
-
private Map metadata = new HashMap();
public Cluster() {
diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Instance.java b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Instance.java
index 129ffd8d9..fcc840ade 100644
--- a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Instance.java
+++ b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Instance.java
@@ -17,7 +17,6 @@ package com.alibaba.nacos.api.naming.pojo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
-import com.alibaba.nacos.api.common.Constants;
import java.util.HashMap;
import java.util.Map;
@@ -55,17 +54,17 @@ public class Instance {
@JSONField(name = "valid")
private boolean healthy = true;
+ private boolean enabled = true;
+
/**
* cluster information of instance
*/
- @JSONField(serialize = false)
- private Cluster cluster = new Cluster();
+ private String clusterName;
/**
- * service information of instance
+ * Service information of instance
*/
- @JSONField(serialize = false)
- private Service service;
+ private String serviceName;
/**
* user extended attributes
@@ -80,14 +79,6 @@ public class Instance {
this.instanceId = instanceId;
}
- public String serviceName() {
- String[] infos = instanceId.split(Constants.NAMING_INSTANCE_ID_SPLITTER);
- if (infos.length < Constants.NAMING_INSTANCE_ID_SEG_COUNT) {
- return null;
- }
- return infos[Constants.NAMING_INSTANCE_ID_SEG_COUNT - 1];
- }
-
public String getIp() {
return ip;
}
@@ -120,20 +111,20 @@ public class Instance {
this.healthy = healthy;
}
- public Cluster getCluster() {
- return cluster;
+ public String getClusterName() {
+ return clusterName;
}
- public void setCluster(Cluster cluster) {
- this.cluster = cluster;
+ public void setClusterName(String clusterName) {
+ this.clusterName = clusterName;
}
- public Service getService() {
- return service;
+ public String getServiceName() {
+ return serviceName;
}
- public void setService(Service service) {
- this.service = service;
+ public void setServiceName(String serviceName) {
+ this.serviceName = serviceName;
}
public Map getMetadata() {
@@ -148,6 +139,14 @@ public class Instance {
this.metadata.put(key, value);
}
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
@Override
public String toString() {
return JSON.toJSONString(this);
@@ -163,7 +162,7 @@ public class Instance {
return false;
}
- Instance host = (Instance) obj;
+ Instance host = (Instance)obj;
return strEquals(toString(), host.toString());
}
diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Service.java b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Service.java
index 630a038ab..098270d8c 100644
--- a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Service.java
+++ b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/Service.java
@@ -15,6 +15,8 @@
*/
package com.alibaba.nacos.api.naming.pojo;
+import com.alibaba.nacos.api.selector.AbstractSelector;
+
import java.util.HashMap;
import java.util.Map;
@@ -41,21 +43,26 @@ public class Service {
private String app;
/**
- * service group which is meant to classify services into different sets.
+ * Service group which is meant to classify services into different sets.
*/
private String group;
/**
- * health check mode.
+ * Health check mode.
*/
private String healthCheckMode;
+ /**
+ * Selector name of this service
+ */
+ private AbstractSelector selector;
+
+ private Map metadata = new HashMap();
+
public Service(String name) {
this.name = name;
}
- private Map metadata = new HashMap();
-
public String getName() {
return name;
}
@@ -107,4 +114,12 @@ public class Service {
public void addMetadata(String key, String value) {
this.metadata.put(key, value);
}
+
+ public AbstractSelector getSelector() {
+ return selector;
+ }
+
+ public void setSelector(AbstractSelector selector) {
+ this.selector = selector;
+ }
}
diff --git a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/ServiceInfo.java b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/ServiceInfo.java
index 6d60c0aae..7b0e369ea 100644
--- a/api/src/main/java/com/alibaba/nacos/api/naming/pojo/ServiceInfo.java
+++ b/api/src/main/java/com/alibaba/nacos/api/naming/pojo/ServiceInfo.java
@@ -17,6 +17,8 @@ package com.alibaba.nacos.api.naming.pojo;
import com.alibaba.fastjson.annotation.JSONField;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -193,6 +195,15 @@ public class ServiceInfo {
return getKey(name, clusters, env, isAllIPs());
}
+ @JSONField(serialize = false)
+ public String getKeyEncoded() {
+ try {
+ return getKey(URLEncoder.encode(name, "UTF-8"), clusters, env, isAllIPs());
+ } catch (UnsupportedEncodingException e) {
+ return getKey();
+ }
+ }
+
@JSONField(serialize = false)
public static String getKey(String name, String clusters, String unit) {
return getKey(name, clusters, unit, false);
@@ -207,7 +218,7 @@ public class ServiceInfo {
if (!isEmpty(clusters) && !isEmpty(unit)) {
return isAllIPs ? name + SPLITER + clusters + SPLITER + unit + SPLITER + ALL_IPS
- : name + SPLITER + clusters + SPLITER + unit;
+ : name + SPLITER + clusters + SPLITER + unit;
}
if (!isEmpty(clusters)) {
@@ -216,7 +227,7 @@ public class ServiceInfo {
if (!isEmpty(unit)) {
return isAllIPs ? name + SPLITER + EMPTY + SPLITER + unit + SPLITER + ALL_IPS :
- name + SPLITER + EMPTY + SPLITER + unit;
+ name + SPLITER + EMPTY + SPLITER + unit;
}
return isAllIPs ? name + SPLITER + ALL_IPS : name;
diff --git a/api/src/main/java/com/alibaba/nacos/api/selector/AbstractSelector.java b/api/src/main/java/com/alibaba/nacos/api/selector/AbstractSelector.java
new file mode 100644
index 000000000..650608c27
--- /dev/null
+++ b/api/src/main/java/com/alibaba/nacos/api/selector/AbstractSelector.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * 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
+ *
+ * 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.nacos.api.selector;
+
+/**
+ * Abstract selector that only contains a type
+ *
+ * @author nkorange
+ */
+public abstract class AbstractSelector {
+
+ /**
+ * The type of this selector, each child class should announce its own unique type.
+ */
+ private String type;
+
+ public String getType() {
+ return type;
+ }
+
+ protected void setType(String type) {
+ this.type = type;
+ }
+}
diff --git a/api/src/main/java/com/alibaba/nacos/api/selector/ExpressionSelector.java b/api/src/main/java/com/alibaba/nacos/api/selector/ExpressionSelector.java
new file mode 100644
index 000000000..35b8f0d43
--- /dev/null
+++ b/api/src/main/java/com/alibaba/nacos/api/selector/ExpressionSelector.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * 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
+ *
+ * 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.nacos.api.selector;
+
+/**
+ * The selector to filter resource with flexible expression.
+ *
+ * @author nkorange
+ */
+public class ExpressionSelector extends AbstractSelector {
+
+ /**
+ * Label expression of this selector.
+ */
+ private String expression;
+
+ public ExpressionSelector() {
+ this.setType(SelectorType.label.name());
+ }
+
+ public String getExpression() {
+ return expression;
+ }
+
+ public void setExpression(String expression) {
+ this.expression = expression;
+ }
+}
diff --git a/api/src/main/java/com/alibaba/nacos/api/selector/SelectorType.java b/api/src/main/java/com/alibaba/nacos/api/selector/SelectorType.java
new file mode 100644
index 000000000..9ec9ab25f
--- /dev/null
+++ b/api/src/main/java/com/alibaba/nacos/api/selector/SelectorType.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * 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
+ *
+ * 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.nacos.api.selector;
+
+/**
+ * The types of selector accepted by Nacos
+ *
+ * @author nkorange
+ */
+public enum SelectorType {
+ /**
+ * not match any type
+ */
+ unknown,
+ /**
+ * not filter out any entity
+ */
+ none,
+ /**
+ * select by label
+ */
+ label
+}
diff --git a/api/src/test/java/com/alibaba/nacos/api/annotation/NacosPropertiesTest.java b/api/src/test/java/com/alibaba/nacos/api/annotation/NacosPropertiesTest.java
index 1bc18fc55..53ed76539 100644
--- a/api/src/test/java/com/alibaba/nacos/api/annotation/NacosPropertiesTest.java
+++ b/api/src/test/java/com/alibaba/nacos/api/annotation/NacosPropertiesTest.java
@@ -1,12 +1,11 @@
/*
- * 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
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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
+ *
+ * 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,
diff --git a/client/pom.xml b/client/pom.xml
index dcf7bcc87..13e8fa403 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -12,113 +12,100 @@
limitations under the License.
-->
-
- com.alibaba.nacos
- nacos-all
- 0.2.1
-
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ com.alibaba.nacos
+ nacos-all
+ 0.7.0
+ ../pom.xml
+
- 4.0.0
+ 4.0.0
- nacos-client
- jar
+ nacos-client
+ jar
- nacos-client ${project.version}
- http://maven.apache.org
+ nacos-client ${project.version}
+ http://maven.apache.org
-
- UTF-8
-
+
+ UTF-8
+
-
-
- org.slf4j
- slf4j-api
- provided
-
-
- log4j
- log4j
- provided
-
-
- org.apache.logging.log4j
- log4j-core
- 2.8.2
- provided
-
-
- commons-logging
- commons-logging
- provided
-
-
- org.slf4j
- slf4j-log4j12
- provided
-
-
- org.apache.logging.log4j
- log4j-slf4j-impl
- provided
-
-
- org.slf4j
- jcl-over-slf4j
- provided
-
-
- junit
- junit
- test
-
-
- ${project.groupId}
- nacos-common
-
-
- ${project.groupId}
- nacos-api
-
-
- com.alibaba
- fastjson
-
+
-
- ch.qos.logback
- logback-classic
-
-
- ch.qos.logback
- logback-core
-
+
+ org.slf4j
+ slf4j-api
+ true
+
-
- com.google.guava
- guava
-
+
+ org.apache.logging.log4j
+ log4j-core
+ 2.8.2
+ true
+
-
- commons-codec
- commons-codec
-
+
+ org.apache.logging.log4j
+ log4j-slf4j-impl
+ true
+
-
- org.codehaus.jackson
- jackson-mapper-lgpl
-
-
- net.jcip
- jcip-annotations
- true
-
-
- com.github.spotbugs
- spotbugs-annotations
- true
-
-
+
+ ${project.groupId}
+ nacos-common
+
+
+ ${project.groupId}
+ nacos-api
+
+
+
+ ch.qos.logback
+ logback-classic
+ true
+
+
+
+ ch.qos.logback
+ logback-core
+ true
+
+
+
+ com.google.guava
+ guava
+
+
+
+ commons-codec
+ commons-codec
+
+
+
+ org.codehaus.jackson
+ jackson-mapper-lgpl
+
+
+ net.jcip
+ jcip-annotations
+ true
+
+
+
+ com.github.spotbugs
+ spotbugs-annotations
+ true
+
+
+
+ junit
+ junit
+ test
+
+
+
diff --git a/client/src/main/java/com/alibaba/nacos/client/config/NacosConfigService.java b/client/src/main/java/com/alibaba/nacos/client/config/NacosConfigService.java
index 8f8b0c51d..3b7680422 100644
--- a/client/src/main/java/com/alibaba/nacos/client/config/NacosConfigService.java
+++ b/client/src/main/java/com/alibaba/nacos/client/config/NacosConfigService.java
@@ -44,233 +44,233 @@ import java.util.Properties;
/**
* Config Impl
- * @author Nacos
*
+ * @author Nacos
*/
@SuppressWarnings("PMD.ServiceOrDaoClassShouldEndWithImplRule")
public class NacosConfigService implements ConfigService {
- final static public Logger log = LogUtils.logger(NacosConfigService.class);
- public final long POST_TIMEOUT = 3000L;
- /**
- * http agent
- */
- private ServerHttpAgent agent;
- /**
- * longpulling
- */
- private ClientWorker worker;
- private String namespace;
- private String encode;
- private ConfigFilterChainManager configFilterChainManager = new ConfigFilterChainManager();
+ final static public Logger log = LogUtils.logger(NacosConfigService.class);
+ public final long POST_TIMEOUT = 3000L;
+ /**
+ * http agent
+ */
+ private ServerHttpAgent agent;
+ /**
+ * longpulling
+ */
+ private ClientWorker worker;
+ private String namespace;
+ private String encode;
+ private ConfigFilterChainManager configFilterChainManager = new ConfigFilterChainManager();
- public NacosConfigService(Properties properties) throws NacosException {
- String encodeTmp = properties.getProperty(PropertyKeyConst.ENCODE);
- if (StringUtils.isBlank(encodeTmp)) {
- encode = Constants.ENCODE;
- } else {
- encode = encodeTmp.trim();
- }
- String namespaceTmp = properties.getProperty(PropertyKeyConst.NAMESPACE);
- if (StringUtils.isBlank(namespaceTmp)) {
- namespace = TenantUtil.getUserTenant();
- properties.put(PropertyKeyConst.NAMESPACE, namespace);
- } else {
- namespace = namespaceTmp;
- properties.put(PropertyKeyConst.NAMESPACE, namespace);
- }
- agent = new ServerHttpAgent(properties);
- agent.start();
- worker = new ClientWorker(agent, configFilterChainManager);
- }
+ public NacosConfigService(Properties properties) throws NacosException {
+ String encodeTmp = properties.getProperty(PropertyKeyConst.ENCODE);
+ if (StringUtils.isBlank(encodeTmp)) {
+ encode = Constants.ENCODE;
+ } else {
+ encode = encodeTmp.trim();
+ }
+ String namespaceTmp = properties.getProperty(PropertyKeyConst.NAMESPACE);
+ if (StringUtils.isBlank(namespaceTmp)) {
+ namespace = TenantUtil.getUserTenant();
+ properties.put(PropertyKeyConst.NAMESPACE, namespace);
+ } else {
+ namespace = namespaceTmp;
+ properties.put(PropertyKeyConst.NAMESPACE, namespace);
+ }
+ agent = new ServerHttpAgent(properties);
+ agent.start();
+ worker = new ClientWorker(agent, configFilterChainManager);
+ }
- @Override
- public String getConfig(String dataId, String group, long timeoutMs) throws NacosException {
- return getConfigInner(namespace, dataId, group, timeoutMs);
- }
+ @Override
+ public String getConfig(String dataId, String group, long timeoutMs) throws NacosException {
+ return getConfigInner(namespace, dataId, group, timeoutMs);
+ }
- @Override
- public void addListener(String dataId, String group, Listener listener) throws NacosException {
- worker.addTenantListeners(dataId, group, Arrays.asList(listener));
- }
+ @Override
+ public void addListener(String dataId, String group, Listener listener) throws NacosException {
+ worker.addTenantListeners(dataId, group, Arrays.asList(listener));
+ }
- @Override
- public boolean publishConfig(String dataId, String group, String content) throws NacosException {
- return publishConfigInner(namespace, dataId, group, null, null, null, content);
- }
+ @Override
+ public boolean publishConfig(String dataId, String group, String content) throws NacosException {
+ return publishConfigInner(namespace, dataId, group, null, null, null, content);
+ }
- @Override
- public boolean removeConfig(String dataId, String group) throws NacosException {
- return removeConfigInner(namespace, dataId, group, null);
- }
+ @Override
+ public boolean removeConfig(String dataId, String group) throws NacosException {
+ return removeConfigInner(namespace, dataId, group, null);
+ }
- @Override
- public void removeListener(String dataId, String group, Listener listener) {
- worker.removeTenantListener(dataId, group, listener);
- }
+ @Override
+ public void removeListener(String dataId, String group, Listener listener) {
+ worker.removeTenantListener(dataId, group, listener);
+ }
- private String getConfigInner(String tenant, String dataId, String group, long timeoutMs) throws NacosException {
- group = null2defaultGroup(group);
- ParamUtils.checkKeyParam(dataId, group);
- ConfigResponse cr = new ConfigResponse();
+ private String getConfigInner(String tenant, String dataId, String group, long timeoutMs) throws NacosException {
+ group = null2defaultGroup(group);
+ ParamUtils.checkKeyParam(dataId, group);
+ ConfigResponse cr = new ConfigResponse();
- cr.setDataId(dataId);
- cr.setTenant(tenant);
- cr.setGroup(group);
+ cr.setDataId(dataId);
+ cr.setTenant(tenant);
+ cr.setGroup(group);
- // 优先使用本地配置
- String content = LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant);
- if (content != null) {
- log.warn(agent.getName(), "[get-config] get failover ok, dataId={}, group={}, tenant={}, config={}", dataId,
- group, tenant, ContentUtils.truncateContent(content));
- cr.setContent(content);
- configFilterChainManager.doFilter(null, cr);
- content = cr.getContent();
- return content;
- }
+ // 优先使用本地配置
+ String content = LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant);
+ if (content != null) {
+ log.warn(agent.getName(), "[get-config] get failover ok, dataId={}, group={}, tenant={}, config={}", dataId,
+ group, tenant, ContentUtils.truncateContent(content));
+ cr.setContent(content);
+ configFilterChainManager.doFilter(null, cr);
+ content = cr.getContent();
+ return content;
+ }
- try {
- content = worker.getServerConfig(dataId, group, tenant, timeoutMs);
- cr.setContent(content);
- configFilterChainManager.doFilter(null, cr);
- content = cr.getContent();
- return content;
- } catch (NacosException ioe) {
- if (NacosException.NO_RIGHT == ioe.getErrCode()) {
- throw ioe;
- }
- log.warn("NACOS-0003",
- LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0003", "环境问题", "get from server error"));
- log.warn(agent.getName(), "[get-config] get from server error, dataId={}, group={}, tenant={}, msg={}",
- dataId, group, tenant, ioe.toString());
- }
+ try {
+ content = worker.getServerConfig(dataId, group, tenant, timeoutMs);
+ cr.setContent(content);
+ configFilterChainManager.doFilter(null, cr);
+ content = cr.getContent();
+ return content;
+ } catch (NacosException ioe) {
+ if (NacosException.NO_RIGHT == ioe.getErrCode()) {
+ throw ioe;
+ }
+ log.warn("NACOS-0003",
+ LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0003", "环境问题", "get from server error"));
+ log.warn(agent.getName(), "[get-config] get from server error, dataId={}, group={}, tenant={}, msg={}",
+ dataId, group, tenant, ioe.toString());
+ }
- log.warn(agent.getName(), "[get-config] get snapshot ok, dataId={}, group={}, tenant={}, config={}", dataId,
- group, tenant, ContentUtils.truncateContent(content));
- content = LocalConfigInfoProcessor.getSnapshot(agent.getName(), dataId, group, tenant);
- cr.setContent(content);
- configFilterChainManager.doFilter(null, cr);
- content = cr.getContent();
- return content;
- }
+ log.warn(agent.getName(), "[get-config] get snapshot ok, dataId={}, group={}, tenant={}, config={}", dataId,
+ group, tenant, ContentUtils.truncateContent(content));
+ content = LocalConfigInfoProcessor.getSnapshot(agent.getName(), dataId, group, tenant);
+ cr.setContent(content);
+ configFilterChainManager.doFilter(null, cr);
+ content = cr.getContent();
+ return content;
+ }
- private String null2defaultGroup(String group) {
- return (null == group) ? Constants.DEFAULT_GROUP : group.trim();
- }
+ private String null2defaultGroup(String group) {
+ return (null == group) ? Constants.DEFAULT_GROUP : group.trim();
+ }
- private boolean removeConfigInner(String tenant, String dataId, String group, String tag) throws NacosException {
- group = null2defaultGroup(group);
- ParamUtils.checkKeyParam(dataId, group);
- String url = Constants.CONFIG_CONTROLLER_PATH;
- List params = new ArrayList();
- params.add("dataId");
- params.add(dataId);
- params.add("group");
- params.add(group);
- if (StringUtils.isNotEmpty(tenant)) {
- params.add("tenant");
- params.add(tenant);
- }
- if (StringUtils.isNotEmpty(tag)) {
- params.add("tag");
- params.add(tag);
- }
- HttpResult result = null;
- try {
- result = agent.httpDelete(url, null, params, encode, POST_TIMEOUT);
- } catch (IOException ioe) {
- log.warn("[remove] error, " + dataId + ", " + group + ", " + tenant + ", msg: " + ioe.toString());
- return false;
- }
+ private boolean removeConfigInner(String tenant, String dataId, String group, String tag) throws NacosException {
+ group = null2defaultGroup(group);
+ ParamUtils.checkKeyParam(dataId, group);
+ String url = Constants.CONFIG_CONTROLLER_PATH;
+ List params = new ArrayList();
+ params.add("dataId");
+ params.add(dataId);
+ params.add("group");
+ params.add(group);
+ if (StringUtils.isNotEmpty(tenant)) {
+ params.add("tenant");
+ params.add(tenant);
+ }
+ if (StringUtils.isNotEmpty(tag)) {
+ params.add("tag");
+ params.add(tag);
+ }
+ HttpResult result = null;
+ try {
+ result = agent.httpDelete(url, null, params, encode, POST_TIMEOUT);
+ } catch (IOException ioe) {
+ log.warn("[remove] error, " + dataId + ", " + group + ", " + tenant + ", msg: " + ioe.toString());
+ return false;
+ }
- if (HttpURLConnection.HTTP_OK == result.code) {
- log.info(agent.getName(), "[remove] ok, dataId={}, group={}, tenant={}", dataId, group, tenant);
- return true;
- } else if (HttpURLConnection.HTTP_FORBIDDEN == result.code) {
- log.warn(agent.getName(), "[remove] error, dataId={}, group={}, tenant={}, code={}, msg={}", dataId, group,
- tenant, result.code, result.content);
- throw new NacosException(result.code, result.content);
- } else {
- log.warn(agent.getName(), "[remove] error, dataId={}, group={}, tenant={}, code={}, msg={}", dataId, group,
- tenant, result.code, result.content);
- return false;
- }
- }
+ if (HttpURLConnection.HTTP_OK == result.code) {
+ log.info(agent.getName(), "[remove] ok, dataId={}, group={}, tenant={}", dataId, group, tenant);
+ return true;
+ } else if (HttpURLConnection.HTTP_FORBIDDEN == result.code) {
+ log.warn(agent.getName(), "[remove] error, dataId={}, group={}, tenant={}, code={}, msg={}", dataId, group,
+ tenant, result.code, result.content);
+ throw new NacosException(result.code, result.content);
+ } else {
+ log.warn(agent.getName(), "[remove] error, dataId={}, group={}, tenant={}, code={}, msg={}", dataId, group,
+ tenant, result.code, result.content);
+ return false;
+ }
+ }
- private boolean publishConfigInner(String tenant, String dataId, String group, String tag, String appName,
- String betaIps, String content) throws NacosException {
- group = null2defaultGroup(group);
- ParamUtils.checkParam(dataId, group, content);
+ private boolean publishConfigInner(String tenant, String dataId, String group, String tag, String appName,
+ String betaIps, String content) throws NacosException {
+ group = null2defaultGroup(group);
+ ParamUtils.checkParam(dataId, group, content);
- ConfigRequest cr = new ConfigRequest();
- cr.setDataId(dataId);
- cr.setTenant(tenant);
- cr.setGroup(group);
- cr.setContent(content);
- configFilterChainManager.doFilter(cr, null);
- content = cr.getContent();
+ ConfigRequest cr = new ConfigRequest();
+ cr.setDataId(dataId);
+ cr.setTenant(tenant);
+ cr.setGroup(group);
+ cr.setContent(content);
+ configFilterChainManager.doFilter(cr, null);
+ content = cr.getContent();
- String url = Constants.CONFIG_CONTROLLER_PATH;
- List params = new ArrayList();
- params.add("dataId");
- params.add(dataId);
- params.add("group");
- params.add(group);
- params.add("content");
- params.add(content);
- if (StringUtils.isNotEmpty(tenant)) {
- params.add("tenant");
- params.add(tenant);
- }
- if (StringUtils.isNotEmpty(appName)) {
- params.add("appName");
- params.add(appName);
- }
- if (StringUtils.isNotEmpty(tag)) {
- params.add("tag");
- params.add(tag);
- }
+ String url = Constants.CONFIG_CONTROLLER_PATH;
+ List params = new ArrayList();
+ params.add("dataId");
+ params.add(dataId);
+ params.add("group");
+ params.add(group);
+ params.add("content");
+ params.add(content);
+ if (StringUtils.isNotEmpty(tenant)) {
+ params.add("tenant");
+ params.add(tenant);
+ }
+ if (StringUtils.isNotEmpty(appName)) {
+ params.add("appName");
+ params.add(appName);
+ }
+ if (StringUtils.isNotEmpty(tag)) {
+ params.add("tag");
+ params.add(tag);
+ }
- List headers = new ArrayList();
- if (StringUtils.isNotEmpty(betaIps)) {
- headers.add("betaIps");
- headers.add(betaIps);
- }
+ List headers = new ArrayList();
+ if (StringUtils.isNotEmpty(betaIps)) {
+ headers.add("betaIps");
+ headers.add(betaIps);
+ }
- HttpResult result = null;
- try {
- result = agent.httpPost(url, headers, params, encode, POST_TIMEOUT);
- } catch (IOException ioe) {
- log.warn("NACOS-0006",
- LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0006", "环境问题", "[publish-single] exception"));
- log.warn(agent.getName(), "[publish-single] exception, dataId={}, group={}, msg={}", dataId, group,
- ioe.toString());
- return false;
- }
+ HttpResult result = null;
+ try {
+ result = agent.httpPost(url, headers, params, encode, POST_TIMEOUT);
+ } catch (IOException ioe) {
+ log.warn("NACOS-0006",
+ LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0006", "环境问题", "[publish-single] exception"));
+ log.warn(agent.getName(), "[publish-single] exception, dataId={}, group={}, msg={}", dataId, group,
+ ioe.toString());
+ return false;
+ }
- if (HttpURLConnection.HTTP_OK == result.code) {
- log.info(agent.getName(), "[publish-single] ok, dataId={}, group={}, tenant={}, config={}", dataId, group,
- tenant, ContentUtils.truncateContent(content));
- return true;
- } else if (HttpURLConnection.HTTP_FORBIDDEN == result.code) {
- log.warn(agent.getName(), "[publish-single] error, dataId={}, group={}, tenant={}, code={}, msg={}", dataId,
- group, tenant, result.code, result.content);
- throw new NacosException(result.code, result.content);
- } else {
- log.warn(agent.getName(), "[publish-single] error, dataId={}, group={}, tenant={}, code={}, msg={}", dataId,
- group, tenant, result.code, result.content);
- return false;
- }
+ if (HttpURLConnection.HTTP_OK == result.code) {
+ log.info(agent.getName(), "[publish-single] ok, dataId={}, group={}, tenant={}, config={}", dataId, group,
+ tenant, ContentUtils.truncateContent(content));
+ return true;
+ } else if (HttpURLConnection.HTTP_FORBIDDEN == result.code) {
+ log.warn(agent.getName(), "[publish-single] error, dataId={}, group={}, tenant={}, code={}, msg={}", dataId,
+ group, tenant, result.code, result.content);
+ throw new NacosException(result.code, result.content);
+ } else {
+ log.warn(agent.getName(), "[publish-single] error, dataId={}, group={}, tenant={}, code={}, msg={}", dataId,
+ group, tenant, result.code, result.content);
+ return false;
+ }
- }
+ }
- @Override
- public String getServerStatus() {
- if (worker.isHealthServer()) {
- return "UP";
- } else {
- return "DOWN";
- }
- }
+ @Override
+ public String getServerStatus() {
+ if (worker.isHealthServer()) {
+ return "UP";
+ } else {
+ return "DOWN";
+ }
+ }
}
diff --git a/client/src/main/java/com/alibaba/nacos/client/config/common/GroupKey.java b/client/src/main/java/com/alibaba/nacos/client/config/common/GroupKey.java
index fce61eddc..5b2465162 100644
--- a/client/src/main/java/com/alibaba/nacos/client/config/common/GroupKey.java
+++ b/client/src/main/java/com/alibaba/nacos/client/config/common/GroupKey.java
@@ -18,9 +18,8 @@ package com.alibaba.nacos.client.config.common;
import com.alibaba.nacos.client.utils.StringUtils;
/**
- * Synthesize the form of dataId+groupId. Escapes reserved characters in dataId
- * and groupId.
- *
+ * Synthesize the form of dataId+groupId. Escapes reserved characters in dataId and groupId.
+ *
* @author Nacos
*/
public class GroupKey {
@@ -33,28 +32,28 @@ public class GroupKey {
return sb.toString();
}
- static public String getKeyTenant(String dataId, String group, String tenant) {
- StringBuilder sb = new StringBuilder();
- urlEncode(dataId, sb);
- sb.append('+');
- urlEncode(group, sb);
- if (StringUtils.isNotEmpty(tenant)) {
- sb.append('+');
- urlEncode(tenant, sb);
- }
- return sb.toString();
- }
-
- static public String getKey(String dataId, String group, String datumStr) {
- StringBuilder sb = new StringBuilder();
- urlEncode(dataId, sb);
- sb.append('+');
- urlEncode(group, sb);
- sb.append('+');
- urlEncode(datumStr, sb);
- return sb.toString();
- }
-
+ static public String getKeyTenant(String dataId, String group, String tenant) {
+ StringBuilder sb = new StringBuilder();
+ urlEncode(dataId, sb);
+ sb.append('+');
+ urlEncode(group, sb);
+ if (StringUtils.isNotEmpty(tenant)) {
+ sb.append('+');
+ urlEncode(tenant, sb);
+ }
+ return sb.toString();
+ }
+
+ static public String getKey(String dataId, String group, String datumStr) {
+ StringBuilder sb = new StringBuilder();
+ urlEncode(dataId, sb);
+ sb.append('+');
+ urlEncode(group, sb);
+ sb.append('+');
+ urlEncode(datumStr, sb);
+ return sb.toString();
+ }
+
static public String[] parseKey(String groupKey) {
StringBuilder sb = new StringBuilder();
String dataId = null;
@@ -64,15 +63,15 @@ public class GroupKey {
for (int i = 0; i < groupKey.length(); ++i) {
char c = groupKey.charAt(i);
if ('+' == c) {
- if (null == dataId) {
- dataId = sb.toString();
- sb.setLength(0);
- } else if (null == group) {
- group = sb.toString();
- sb.setLength(0);
- } else {
- throw new IllegalArgumentException("invalid groupkey:" + groupKey);
- }
+ if (null == dataId) {
+ dataId = sb.toString();
+ sb.setLength(0);
+ } else if (null == group) {
+ group = sb.toString();
+ sb.setLength(0);
+ } else {
+ throw new IllegalArgumentException("invalid groupkey:" + groupKey);
+ }
} else if ('%' == c) {
char next = groupKey.charAt(++i);
char nextnext = groupKey.charAt(++i);
@@ -87,25 +86,24 @@ public class GroupKey {
sb.append(c);
}
}
-
- if (StringUtils.isBlank(group)) {
- group = sb.toString();
- if (group.length() == 0) {
- throw new IllegalArgumentException("invalid groupkey:" + groupKey);
- }
- } else {
- tenant = sb.toString();
- if (group.length() == 0) {
- throw new IllegalArgumentException("invalid groupkey:" + groupKey);
- }
- }
-
- return new String[] { dataId, group, tenant };
+
+ if (StringUtils.isBlank(group)) {
+ group = sb.toString();
+ if (group.length() == 0) {
+ throw new IllegalArgumentException("invalid groupkey:" + groupKey);
+ }
+ } else {
+ tenant = sb.toString();
+ if (group.length() == 0) {
+ throw new IllegalArgumentException("invalid groupkey:" + groupKey);
+ }
+ }
+
+ return new String[] {dataId, group, tenant};
}
-
+
/**
- * + -> %2B
- * % -> %25
+ * + -> %2B % -> %25
*/
static void urlEncode(String str, StringBuilder sb) {
for (int idx = 0; idx < str.length(); ++idx) {
diff --git a/client/src/main/java/com/alibaba/nacos/client/config/filter/impl/ConfigContext.java b/client/src/main/java/com/alibaba/nacos/client/config/filter/impl/ConfigContext.java
index 23c65f6ec..834a6d5dc 100644
--- a/client/src/main/java/com/alibaba/nacos/client/config/filter/impl/ConfigContext.java
+++ b/client/src/main/java/com/alibaba/nacos/client/config/filter/impl/ConfigContext.java
@@ -22,22 +22,21 @@ import com.alibaba.nacos.api.config.filter.IConfigContext;
/**
* Config Context
- *
- * @author Nacos
*
+ * @author Nacos
*/
public class ConfigContext implements IConfigContext {
- private Map param = new HashMap();
+ private Map param = new HashMap();
- @Override
- public Object getParameter(String key) {
- return param.get(key);
- }
+ @Override
+ public Object getParameter(String key) {
+ return param.get(key);
+ }
- @Override
- public void setParameter(String key, Object value) {
- param.put(key, value);
- }
+ @Override
+ public void setParameter(String key, Object value) {
+ param.put(key, value);
+ }
}
diff --git a/client/src/main/java/com/alibaba/nacos/client/config/filter/impl/ConfigFilterChainManager.java b/client/src/main/java/com/alibaba/nacos/client/config/filter/impl/ConfigFilterChainManager.java
index 1566113ed..f06fde03f 100644
--- a/client/src/main/java/com/alibaba/nacos/client/config/filter/impl/ConfigFilterChainManager.java
+++ b/client/src/main/java/com/alibaba/nacos/client/config/filter/impl/ConfigFilterChainManager.java
@@ -26,62 +26,60 @@ import com.google.common.collect.Lists;
/**
* Config Filter Chain Management
- *
- * @author Nacos
*
+ * @author Nacos
*/
public class ConfigFilterChainManager implements IConfigFilterChain {
- private List filters = Lists.newArrayList();
+ private List filters = Lists.newArrayList();
- public synchronized ConfigFilterChainManager addFilter(IConfigFilter filter) {
- // 根据order大小顺序插入
- int i = 0;
- while (i < this.filters.size()) {
- IConfigFilter currentValue = this.filters.get(i);
- if (currentValue.getFilterName().equals(filter.getFilterName())) {
- break;
- }
- if (filter.getOrder() >= currentValue.getOrder() && i < this.filters.size()) {
- i++;
- } else {
- this.filters.add(i, filter);
- break;
- }
- }
+ public synchronized ConfigFilterChainManager addFilter(IConfigFilter filter) {
+ // 根据order大小顺序插入
+ int i = 0;
+ while (i < this.filters.size()) {
+ IConfigFilter currentValue = this.filters.get(i);
+ if (currentValue.getFilterName().equals(filter.getFilterName())) {
+ break;
+ }
+ if (filter.getOrder() >= currentValue.getOrder() && i < this.filters.size()) {
+ i++;
+ } else {
+ this.filters.add(i, filter);
+ break;
+ }
+ }
- if (i == this.filters.size()) {
- this.filters.add(i, filter);
- }
- return this;
- }
-
+ if (i == this.filters.size()) {
+ this.filters.add(i, filter);
+ }
+ return this;
+ }
- @Override
- public void doFilter(IConfigRequest request, IConfigResponse response) throws NacosException {
- new VirtualFilterChain(this.filters).doFilter(request, response);
- }
+ @Override
+ public void doFilter(IConfigRequest request, IConfigResponse response) throws NacosException {
+ new VirtualFilterChain(this.filters).doFilter(request, response);
+ }
- private static class VirtualFilterChain implements IConfigFilterChain {
+ private static class VirtualFilterChain implements IConfigFilterChain {
- private final List extends IConfigFilter> additionalFilters;
+ private final List extends IConfigFilter> additionalFilters;
- private int currentPosition = 0;
+ private int currentPosition = 0;
- public VirtualFilterChain(List extends IConfigFilter> additionalFilters) {
- this.additionalFilters = additionalFilters;
- }
+ public VirtualFilterChain(List extends IConfigFilter> additionalFilters) {
+ this.additionalFilters = additionalFilters;
+ }
- @Override
- public void doFilter(final IConfigRequest request, final IConfigResponse response) throws NacosException {
- if (this.currentPosition == this.additionalFilters.size()) {
- return;
- } else {
- this.currentPosition++;
- IConfigFilter nextFilter = this.additionalFilters.get(this.currentPosition - 1);
- nextFilter.doFilter(request, response, this);
- }
- }
- }
+ @Override
+ public void doFilter(final IConfigRequest request, final IConfigResponse response) throws NacosException {
+ if (this.currentPosition == this.additionalFilters.size()) {
+ return;
+ } else {
+ this.currentPosition++;
+ IConfigFilter nextFilter = this.additionalFilters.get(this.currentPosition - 1);
+ nextFilter.doFilter(request, response, this);
+ }
+ }
+ }
}
diff --git a/client/src/main/java/com/alibaba/nacos/client/config/filter/impl/ConfigRequest.java b/client/src/main/java/com/alibaba/nacos/client/config/filter/impl/ConfigRequest.java
index 100b10d39..76294724f 100644
--- a/client/src/main/java/com/alibaba/nacos/client/config/filter/impl/ConfigRequest.java
+++ b/client/src/main/java/com/alibaba/nacos/client/config/filter/impl/ConfigRequest.java
@@ -23,56 +23,55 @@ import com.alibaba.nacos.api.config.filter.IConfigRequest;
/**
* Config Request
- *
- * @author Nacos
*
+ * @author Nacos
*/
public class ConfigRequest implements IConfigRequest {
- private Map param = new HashMap();
+ private Map param = new HashMap();
- private IConfigContext configContext = new ConfigContext();
+ private IConfigContext configContext = new ConfigContext();
- public String getTenant() {
- return (String) param.get("tenant");
- }
+ public String getTenant() {
+ return (String)param.get("tenant");
+ }
- public void setTenant(String tenant) {
- param.put("tenant", tenant);
- }
+ public void setTenant(String tenant) {
+ param.put("tenant", tenant);
+ }
- public String getDataId() {
- return (String) param.get("dataId");
- }
+ public String getDataId() {
+ return (String)param.get("dataId");
+ }
- public void setDataId(String dataId) {
- param.put("dataId", dataId);
- }
+ public void setDataId(String dataId) {
+ param.put("dataId", dataId);
+ }
- public String getGroup() {
- return (String) param.get("group");
- }
+ public String getGroup() {
+ return (String)param.get("group");
+ }
- public void setGroup(String group) {
- param.put("group", group);
- }
+ public void setGroup(String group) {
+ param.put("group", group);
+ }
- public String getContent() {
- return (String) param.get("content");
- }
+ public String getContent() {
+ return (String)param.get("content");
+ }
- public void setContent(String content) {
- param.put("content", content);
- }
+ public void setContent(String content) {
+ param.put("content", content);
+ }
- @Override
- public Object getParameter(String key) {
- return param.get(key);
- }
+ @Override
+ public Object getParameter(String key) {
+ return param.get(key);
+ }
- @Override
- public IConfigContext getConfigContext() {
- return configContext;
- }
+ @Override
+ public IConfigContext getConfigContext() {
+ return configContext;
+ }
}
diff --git a/client/src/main/java/com/alibaba/nacos/client/config/filter/impl/ConfigResponse.java b/client/src/main/java/com/alibaba/nacos/client/config/filter/impl/ConfigResponse.java
index c864331cc..c009fc289 100644
--- a/client/src/main/java/com/alibaba/nacos/client/config/filter/impl/ConfigResponse.java
+++ b/client/src/main/java/com/alibaba/nacos/client/config/filter/impl/ConfigResponse.java
@@ -23,56 +23,55 @@ import com.alibaba.nacos.api.config.filter.IConfigResponse;
/**
* Config Response
- *
- * @author Nacos
*
+ * @author Nacos
*/
public class ConfigResponse implements IConfigResponse {
- private Map param = new HashMap();
+ private Map param = new HashMap();
- private IConfigContext configContext = new ConfigContext();
+ private IConfigContext configContext = new ConfigContext();
- public String getTenant() {
- return (String) param.get("tenant");
- }
+ public String getTenant() {
+ return (String)param.get("tenant");
+ }
- public void setTenant(String tenant) {
- param.put("tenant", tenant);
- }
+ public void setTenant(String tenant) {
+ param.put("tenant", tenant);
+ }
- public String getDataId() {
- return (String) param.get("dataId");
- }
+ public String getDataId() {
+ return (String)param.get("dataId");
+ }
- public void setDataId(String dataId) {
- param.put("dataId", dataId);
- }
+ public void setDataId(String dataId) {
+ param.put("dataId", dataId);
+ }
- public String getGroup() {
- return (String) param.get("group");
- }
+ public String getGroup() {
+ return (String)param.get("group");
+ }
- public void setGroup(String group) {
- param.put("group", group);
- }
+ public void setGroup(String group) {
+ param.put("group", group);
+ }
- public String getContent() {
- return (String) param.get("content");
- }
+ public String getContent() {
+ return (String)param.get("content");
+ }
- public void setContent(String content) {
- param.put("content", content);
- }
+ public void setContent(String content) {
+ param.put("content", content);
+ }
- @Override
- public Object getParameter(String key) {
- return param.get(key);
- }
+ @Override
+ public Object getParameter(String key) {
+ return param.get(key);
+ }
- @Override
- public IConfigContext getConfigContext() {
- return configContext;
- }
+ @Override
+ public IConfigContext getConfigContext() {
+ return configContext;
+ }
}
diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java
index 9ca7822e9..0b3dfa147 100644
--- a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java
+++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java
@@ -32,56 +32,54 @@ import java.util.concurrent.CopyOnWriteArrayList;
/**
* Listner Management
- *
- * @author Nacos
*
+ * @author Nacos
*/
public class CacheData {
- final static public Logger log = LogUtils.logger(CacheData.class);
-
- public boolean isInitializing() {
- return isInitializing;
- }
+ final static public Logger log = LogUtils.logger(CacheData.class);
- public void setInitializing(boolean isInitializing) {
- this.isInitializing = isInitializing;
- }
+ public boolean isInitializing() {
+ return isInitializing;
+ }
- public String getMd5() {
+ public void setInitializing(boolean isInitializing) {
+ this.isInitializing = isInitializing;
+ }
+
+ public String getMd5() {
return md5;
}
-
- public String getTenant() {
- return tenant;
- }
+
+ public String getTenant() {
+ return tenant;
+ }
public String getContent() {
return content;
}
-
+
public void setContent(String newContent) {
this.content = newContent;
this.md5 = getMd5String(content);
}
-
- /**
- * Add listener
- *
- * @param listener
- * listener
- */
- public void addListener(Listener listener) {
- if (null == listener) {
- throw new IllegalArgumentException("listener is null");
- }
- ManagerListenerWrap wrap = new ManagerListenerWrap(listener);
- if (listeners.addIfAbsent(wrap)) {
- log.info(name, "[add-listener] ok, tenant={}, dataId={}, group={}, cnt={}", tenant, dataId, group,
- listeners.size());
- }
- }
-
+
+ /**
+ * Add listener
+ *
+ * @param listener listener
+ */
+ public void addListener(Listener listener) {
+ if (null == listener) {
+ throw new IllegalArgumentException("listener is null");
+ }
+ ManagerListenerWrap wrap = new ManagerListenerWrap(listener);
+ if (listeners.addIfAbsent(wrap)) {
+ log.info(name, "[add-listener] ok, tenant={}, dataId={}, group={}, cnt={}", tenant, dataId, group,
+ listeners.size());
+ }
+ }
+
public void removeListener(Listener listener) {
if (null == listener) {
throw new IllegalArgumentException("listener is null");
@@ -91,7 +89,7 @@ public class CacheData {
log.info(name, "[remove-listener] ok, dataId={}, group={}, cnt={}", dataId, group, listeners.size());
}
}
-
+
/**
* 返回监听器列表上的迭代器,只读。保证不返回NULL。
*/
@@ -103,32 +101,32 @@ public class CacheData {
return result;
}
-
public long getLocalConfigInfoVersion() {
return localConfigLastModified;
}
+
public void setLocalConfigInfoVersion(long localConfigLastModified) {
this.localConfigLastModified = localConfigLastModified;
}
-
public boolean isUseLocalConfigInfo() {
return isUseLocalConfig;
}
+
public void setUseLocalConfigInfo(boolean useLocalConfigInfo) {
this.isUseLocalConfig = useLocalConfigInfo;
if (!useLocalConfigInfo) {
localConfigLastModified = -1;
}
}
-
- public int getTaskId() {
- return taskId;
- }
- public void setTaskId(int taskId) {
- this.taskId = taskId;
- }
+ public int getTaskId() {
+ return taskId;
+ }
+
+ public void setTaskId(int taskId) {
+ this.taskId = taskId;
+ }
@Override
public int hashCode() {
@@ -147,7 +145,7 @@ public class CacheData {
if (this == obj) {
return true;
}
- CacheData other = (CacheData) obj;
+ CacheData other = (CacheData)obj;
return dataId.equals(other.dataId) && group.equals(other.group);
}
@@ -155,7 +153,7 @@ public class CacheData {
public String toString() {
return "CacheData [" + dataId + ", " + group + "]";
}
-
+
void checkListenerMd5() {
for (ManagerListenerWrap wrap : listeners) {
if (!md5.equals(wrap.lastCallMd5)) {
@@ -163,48 +161,46 @@ public class CacheData {
}
}
}
-
+
private void safeNotifyListener(final String dataId, final String group, final String content,
- final String md5, final ManagerListenerWrap listenerWrap) {
+ final String md5, final ManagerListenerWrap listenerWrap) {
final Listener listener = listenerWrap.listener;
-
+
Runnable job = new Runnable() {
public void run() {
- ClassLoader myClassLoader = Thread.currentThread().getContextClassLoader();
- ClassLoader appClassLoader= listener.getClass().getClassLoader();
+ ClassLoader myClassLoader = Thread.currentThread().getContextClassLoader();
+ ClassLoader appClassLoader = listener.getClass().getClassLoader();
try {
- if(listener instanceof AbstractSharedListener){
- AbstractSharedListener adapter = (AbstractSharedListener) listener;
+ if (listener instanceof AbstractSharedListener) {
+ AbstractSharedListener adapter = (AbstractSharedListener)listener;
adapter.fillContext(dataId, group);
log.info(name, "[notify-context] dataId={}, group={}, md5={}", dataId, group, md5);
}
// 执行回调之前先将线程classloader设置为具体webapp的classloader,以免回调方法中调用spi接口是出现异常或错用(多应用部署才会有该问题)。
Thread.currentThread().setContextClassLoader(appClassLoader);
-
- ConfigResponse cr = new ConfigResponse();
- cr.setDataId(dataId);
- cr.setGroup(group);
- cr.setContent(content);
- configFilterChainManager.doFilter(null, cr);
- String contentTmp = cr.getContent();
- listener.receiveConfigInfo(contentTmp);
- listenerWrap.lastCallMd5 = md5;
- log.info(
- name,
- "[notify-ok] dataId={}, group={}, md5={}, listener={} ",
- dataId, group, md5, listener);
- } catch (NacosException de) {
- log.error(name, "NACOS-XXXX",
- "[notify-error] dataId={}, group={}, md5={}, listener={} errCode={} errMsg={}", dataId,
- group, md5, listener, de.getErrCode(), de.getErrMsg());
- } catch (Throwable t) {
- log.error(name, "NACOS-XXXX",
- "[notify-error] dataId={}, group={}, md5={}, listener={} tx={}", dataId, group, md5,
- listener, t.getCause());
- }
- finally
- {
- Thread.currentThread().setContextClassLoader(myClassLoader);
+
+ ConfigResponse cr = new ConfigResponse();
+ cr.setDataId(dataId);
+ cr.setGroup(group);
+ cr.setContent(content);
+ configFilterChainManager.doFilter(null, cr);
+ String contentTmp = cr.getContent();
+ listener.receiveConfigInfo(contentTmp);
+ listenerWrap.lastCallMd5 = md5;
+ log.info(
+ name,
+ "[notify-ok] dataId={}, group={}, md5={}, listener={} ",
+ dataId, group, md5, listener);
+ } catch (NacosException de) {
+ log.error(name, "NACOS-XXXX",
+ "[notify-error] dataId={}, group={}, md5={}, listener={} errCode={} errMsg={}", dataId,
+ group, md5, listener, de.getErrCode(), de.getErrMsg());
+ } catch (Throwable t) {
+ log.error(name, "NACOS-XXXX",
+ "[notify-error] dataId={}, group={}, md5={}, listener={} tx={}", dataId, group, md5,
+ listener, t.getCause());
+ } finally {
+ Thread.currentThread().setContextClassLoader(myClassLoader);
}
}
};
@@ -217,57 +213,59 @@ public class CacheData {
job.run();
}
} catch (Throwable t) {
- log.error(
- name,
- "NACOS-XXXX",
- "[notify-error] dataId={}, group={}, md5={}, listener={} throwable={}",
- dataId, group, md5, listener, t.getCause());
+ log.error(
+ name,
+ "NACOS-XXXX",
+ "[notify-error] dataId={}, group={}, md5={}, listener={} throwable={}",
+ dataId, group, md5, listener, t.getCause());
}
final long finishNotify = System.currentTimeMillis();
- log.info(name, "[notify-listener] time cost={}ms in ClientWorker, dataId={}, group={}, md5={}, listener={} ",(finishNotify - startNotify), dataId ,group, md5, listener);
+ log.info(name, "[notify-listener] time cost={}ms in ClientWorker, dataId={}, group={}, md5={}, listener={} ",
+ (finishNotify - startNotify), dataId, group, md5, listener);
}
-
+
static public String getMd5String(String config) {
return (null == config) ? Constants.NULL : MD5.getInstance().getMD5String(config);
}
private String loadCacheContentFromDiskLocal(String name, String dataId, String group, String tenant) {
- String content = LocalConfigInfoProcessor.getFailover(name, dataId, group, tenant);
- content = (null != content) ? content
- : LocalConfigInfoProcessor.getSnapshot(name, dataId, group, tenant);
- return content;
+ String content = LocalConfigInfoProcessor.getFailover(name, dataId, group, tenant);
+ content = (null != content) ? content
+ : LocalConfigInfoProcessor.getSnapshot(name, dataId, group, tenant);
+ return content;
}
-
- public CacheData(ConfigFilterChainManager configFilterChainManager, String name, String dataId, String group) {
- if (null == dataId || null == group) {
- throw new IllegalArgumentException("dataId=" + dataId + ", group=" + group);
- }
- this.name = name;
- this.configFilterChainManager = configFilterChainManager;
- this.dataId = dataId;
- this.group = group;
- this.tenant = TenantUtil.getUserTenant();
- listeners = new CopyOnWriteArrayList();
- this.isInitializing = true;
- this.content = loadCacheContentFromDiskLocal(name, dataId, group, tenant);
- this.md5 = getMd5String(content);
+
+ public CacheData(ConfigFilterChainManager configFilterChainManager, String name, String dataId, String group) {
+ if (null == dataId || null == group) {
+ throw new IllegalArgumentException("dataId=" + dataId + ", group=" + group);
+ }
+ this.name = name;
+ this.configFilterChainManager = configFilterChainManager;
+ this.dataId = dataId;
+ this.group = group;
+ this.tenant = TenantUtil.getUserTenant();
+ listeners = new CopyOnWriteArrayList();
+ this.isInitializing = true;
+ this.content = loadCacheContentFromDiskLocal(name, dataId, group, tenant);
+ this.md5 = getMd5String(content);
}
-
- public CacheData(ConfigFilterChainManager configFilterChainManager, String name, String dataId, String group, String tenant) {
- if (null == dataId || null == group) {
- throw new IllegalArgumentException("dataId=" + dataId + ", group=" + group);
- }
- this.name = name;
- this.configFilterChainManager = configFilterChainManager;
- this.dataId = dataId;
- this.group = group;
- this.tenant = tenant;
- listeners = new CopyOnWriteArrayList();
- this.isInitializing = true;
- this.content = loadCacheContentFromDiskLocal(name, dataId, group, tenant);
- this.md5 = getMd5String(content);
+
+ public CacheData(ConfigFilterChainManager configFilterChainManager, String name, String dataId, String group,
+ String tenant) {
+ if (null == dataId || null == group) {
+ throw new IllegalArgumentException("dataId=" + dataId + ", group=" + group);
+ }
+ this.name = name;
+ this.configFilterChainManager = configFilterChainManager;
+ this.dataId = dataId;
+ this.group = group;
+ this.tenant = tenant;
+ listeners = new CopyOnWriteArrayList();
+ this.isInitializing = true;
+ this.content = loadCacheContentFromDiskLocal(name, dataId, group, tenant);
+ this.md5 = getMd5String(content);
}
-
+
// ==================
private final String name;
@@ -277,16 +275,16 @@ public class CacheData {
public final String tenant;
private final CopyOnWriteArrayList listeners;
- private volatile String md5;
- /**
- * whether use local config
- */
- private volatile boolean isUseLocalConfig = false;
- /**
- * last motify time
- */
- private volatile long localConfigLastModified;
- private volatile String content;
+ private volatile String md5;
+ /**
+ * whether use local config
+ */
+ private volatile boolean isUseLocalConfig = false;
+ /**
+ * last motify time
+ */
+ private volatile long localConfigLastModified;
+ private volatile String content;
private int taskId;
private volatile boolean isInitializing = true;
}
@@ -307,13 +305,13 @@ class ManagerListenerWrap {
if (obj == this) {
return true;
}
- ManagerListenerWrap other = (ManagerListenerWrap) obj;
+ ManagerListenerWrap other = (ManagerListenerWrap)obj;
return listener.equals(other.listener);
}
- @Override
- public int hashCode() {
- return super.hashCode();
- }
+ @Override
+ public int hashCode() {
+ return super.hashCode();
+ }
}
diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java
index 201723460..ba86785d4 100644
--- a/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java
+++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java
@@ -44,24 +44,23 @@ import static com.alibaba.nacos.api.common.Constants.WORD_SEPARATOR;
/**
* Longpulling
- *
- * @author Nacos
*
+ * @author Nacos
*/
public class ClientWorker {
-
- final static public Logger log = LogUtils.logger(ClientWorker.class);
- public void addListeners(String dataId, String group, List extends Listener> listeners) {
+ final static public Logger log = LogUtils.logger(ClientWorker.class);
+
+ public void addListeners(String dataId, String group, List extends Listener> listeners) {
group = null2defaultGroup(group);
CacheData cache = addCacheDataIfAbsent(dataId, group);
for (Listener listener : listeners) {
cache.addListener(listener);
}
- }
-
- public void removeListener(String dataId, String group, Listener listener) {
- group = null2defaultGroup(group);
+ }
+
+ public void removeListener(String dataId, String group, Listener listener) {
+ group = null2defaultGroup(group);
CacheData cache = getCache(dataId, group);
if (null != cache) {
cache.removeListener(listener);
@@ -69,30 +68,30 @@ public class ClientWorker {
removeCache(dataId, group);
}
}
- }
-
- public void addTenantListeners(String dataId, String group, List extends Listener> listeners) {
- group = null2defaultGroup(group);
- String tenant = agent.getTenant();
- CacheData cache = addCacheDataIfAbsent(dataId, group, tenant);
- for (Listener listener : listeners) {
- cache.addListener(listener);
- }
- }
-
- public void removeTenantListener(String dataId, String group, Listener listener) {
- group = null2defaultGroup(group);
- String tenant = agent.getTenant();
- CacheData cache = getCache(dataId, group, tenant);
- if (null != cache) {
- cache.removeListener(listener);
- if (cache.getListeners().isEmpty()) {
- removeCache(dataId, group, tenant);
- }
- }
- }
-
- @SuppressFBWarnings("JLM_JSR166_UTILCONCURRENT_MONITORENTER")
+ }
+
+ public void addTenantListeners(String dataId, String group, List extends Listener> listeners) {
+ group = null2defaultGroup(group);
+ String tenant = agent.getTenant();
+ CacheData cache = addCacheDataIfAbsent(dataId, group, tenant);
+ for (Listener listener : listeners) {
+ cache.addListener(listener);
+ }
+ }
+
+ public void removeTenantListener(String dataId, String group, Listener listener) {
+ group = null2defaultGroup(group);
+ String tenant = agent.getTenant();
+ CacheData cache = getCache(dataId, group, tenant);
+ if (null != cache) {
+ cache.removeListener(listener);
+ if (cache.getListeners().isEmpty()) {
+ removeCache(dataId, group, tenant);
+ }
+ }
+ }
+
+ @SuppressFBWarnings("JLM_JSR166_UTILCONCURRENT_MONITORENTER")
void removeCache(String dataId, String group) {
String groupKey = GroupKey.getKey(dataId, group);
synchronized (cacheMap) {
@@ -102,20 +101,20 @@ public class ClientWorker {
}
log.info(agent.getName(), "[unsubscribe] {}", groupKey);
}
-
- @SuppressFBWarnings("JLM_JSR166_UTILCONCURRENT_MONITORENTER")
+
+ @SuppressFBWarnings("JLM_JSR166_UTILCONCURRENT_MONITORENTER")
void removeCache(String dataId, String group, String tenant) {
- String groupKey = GroupKey.getKeyTenant(dataId, group, tenant);
- synchronized (cacheMap) {
- Map copy = new HashMap(cacheMap.get());
- copy.remove(groupKey);
- cacheMap.set(copy);
- }
- log.info(agent.getName(), "[unsubscribe] {}", groupKey);
+ String groupKey = GroupKey.getKeyTenant(dataId, group, tenant);
+ synchronized (cacheMap) {
+ Map copy = new HashMap(cacheMap.get());
+ copy.remove(groupKey);
+ cacheMap.set(copy);
+ }
+ log.info(agent.getName(), "[unsubscribe] {}", groupKey);
}
-
- @SuppressFBWarnings("JLM_JSR166_UTILCONCURRENT_MONITORENTER")
- public CacheData addCacheDataIfAbsent(String dataId, String group) {
+
+ @SuppressFBWarnings("JLM_JSR166_UTILCONCURRENT_MONITORENTER")
+ public CacheData addCacheDataIfAbsent(String dataId, String group) {
CacheData cache = getCache(dataId, group);
if (null != cache) {
return cache;
@@ -123,408 +122,409 @@ public class ClientWorker {
String key = GroupKey.getKey(dataId, group);
cache = new CacheData(configFilterChainManager, agent.getName(), dataId, group);
-
+
synchronized (cacheMap) {
- CacheData cacheFromMap = getCache(dataId, group);
- // multiple listeners on the same dataid+group and race condition,so double check again
- //other listener thread beat me to set to cacheMap
- if(null != cacheFromMap) {
- cache = cacheFromMap;
- //reset so that server not hang this check
- cache.setInitializing(true);
- } else {
- int taskId = cacheMap.get().size() / (int) ParamUtil.getPerTaskConfigSize();
- cache.setTaskId(taskId);
- }
-
+ CacheData cacheFromMap = getCache(dataId, group);
+ // multiple listeners on the same dataid+group and race condition,so double check again
+ //other listener thread beat me to set to cacheMap
+ if (null != cacheFromMap) {
+ cache = cacheFromMap;
+ //reset so that server not hang this check
+ cache.setInitializing(true);
+ } else {
+ int taskId = cacheMap.get().size() / (int)ParamUtil.getPerTaskConfigSize();
+ cache.setTaskId(taskId);
+ }
+
Map copy = new HashMap(cacheMap.get());
copy.put(key, cache);
cacheMap.set(copy);
}
-
+
log.info(agent.getName(), "[subscribe] {}", key);
-
+
return cache;
}
- @SuppressFBWarnings("JLM_JSR166_UTILCONCURRENT_MONITORENTER")
- public CacheData addCacheDataIfAbsent(String dataId, String group, String tenant) {
- CacheData cache = getCache(dataId, group, tenant);
- if (null != cache) {
- return cache;
- }
- String key = GroupKey.getKeyTenant(dataId, group, tenant);
- cache = new CacheData(configFilterChainManager, agent.getName(), dataId, group, tenant);
- synchronized (cacheMap) {
- CacheData cacheFromMap = getCache(dataId, group, tenant);
- // multiple listeners on the same dataid+group and race condition,so
- // double check again
- // other listener thread beat me to set to cacheMap
- if (null != cacheFromMap) {
- cache = cacheFromMap;
- // reset so that server not hang this check
- cache.setInitializing(true);
- }
- Map copy = new HashMap(cacheMap.get());
- copy.put(key, cache);
- cacheMap.set(copy);
- }
- log.info(agent.getName(), "[subscribe] {}", key);
- return cache;
- }
-
- public CacheData getCache(String dataId, String group) {
- return getCache(dataId, group, TenantUtil.getUserTenant());
- }
-
- public CacheData getCache(String dataId, String group, String tenant) {
- if (null == dataId || null == group) {
- throw new IllegalArgumentException();
- }
- return cacheMap.get().get(GroupKey.getKeyTenant(dataId, group, tenant));
- }
-
+ @SuppressFBWarnings("JLM_JSR166_UTILCONCURRENT_MONITORENTER")
+ public CacheData addCacheDataIfAbsent(String dataId, String group, String tenant) {
+ CacheData cache = getCache(dataId, group, tenant);
+ if (null != cache) {
+ return cache;
+ }
+ String key = GroupKey.getKeyTenant(dataId, group, tenant);
+ cache = new CacheData(configFilterChainManager, agent.getName(), dataId, group, tenant);
+ synchronized (cacheMap) {
+ CacheData cacheFromMap = getCache(dataId, group, tenant);
+ // multiple listeners on the same dataid+group and race condition,so
+ // double check again
+ // other listener thread beat me to set to cacheMap
+ if (null != cacheFromMap) {
+ cache = cacheFromMap;
+ // reset so that server not hang this check
+ cache.setInitializing(true);
+ }
- public String getServerConfig(String dataId, String group, String tenant, long readTimeout)
- throws NacosException {
- if (StringUtils.isBlank(group)) {
- group = Constants.DEFAULT_GROUP;
- }
+ Map copy = new HashMap(cacheMap.get());
+ copy.put(key, cache);
+ cacheMap.set(copy);
+ }
+ log.info(agent.getName(), "[subscribe] {}", key);
+ return cache;
+ }
- HttpResult result = null;
- try {
- List params = null;
- if (StringUtils.isBlank(tenant)) {
- params = Arrays.asList("dataId", dataId, "group", group);
- } else {
- params = Arrays.asList("dataId", dataId, "group", group, "tenant", tenant);
- }
- result = agent.httpGet(Constants.CONFIG_CONTROLLER_PATH, null, params, agent.getEncode(), readTimeout);
- } catch (IOException e) {
- log.error(agent.getName(), "NACOS-XXXX",
- "[sub-server] get server config exception, dataId={}, group={}, tenant={}, msg={}", dataId, group,
- tenant, e.toString());
- throw new NacosException(NacosException.SERVER_ERROR, e.getMessage());
- }
+ public CacheData getCache(String dataId, String group) {
+ return getCache(dataId, group, TenantUtil.getUserTenant());
+ }
- switch (result.code) {
- case HttpURLConnection.HTTP_OK:
- LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, result.content);
- return result.content;
- case HttpURLConnection.HTTP_NOT_FOUND:
- LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, null);
- return null;
- case HttpURLConnection.HTTP_CONFLICT: {
- log.error(agent.getName(), "NACOS-XXXX",
- "[sub-server-error] get server config being modified concurrently, dataId={}, group={}, tenant={}",
- dataId, group, tenant);
- throw new NacosException(NacosException.CONFLICT,
- "data being modified, dataId=" + dataId + ",group=" + group + ",tenant=" + tenant);
- }
- case HttpURLConnection.HTTP_FORBIDDEN: {
- log.error(agent.getName(), "NACOS-XXXX", "[sub-server-error] no right, dataId={}, group={}, tenant={}",
- dataId, group, tenant);
- throw new NacosException(result.code, result.content);
- }
- default: {
- log.error(agent.getName(), "NACOS-XXXX", "[sub-server-error] dataId={}, group={}, tenant={}, code={}",
- dataId, group, tenant, result.code);
- throw new NacosException(result.code,
- "http error, code=" + result.code + ",dataId=" + dataId + ",group=" + group + ",tenant=" + tenant);
- }
- }
- }
+ public CacheData getCache(String dataId, String group, String tenant) {
+ if (null == dataId || null == group) {
+ throw new IllegalArgumentException();
+ }
+ return cacheMap.get().get(GroupKey.getKeyTenant(dataId, group, tenant));
+ }
- private void checkLocalConfig(CacheData cacheData) {
- final String dataId = cacheData.dataId;
- final String group = cacheData.group;
- final String tenant = cacheData.tenant;
- File path = LocalConfigInfoProcessor.getFailoverFile(agent.getName(), dataId, group, tenant);
+ public String getServerConfig(String dataId, String group, String tenant, long readTimeout)
+ throws NacosException {
+ if (StringUtils.isBlank(group)) {
+ group = Constants.DEFAULT_GROUP;
+ }
- // 没有 -> 有
- if (!cacheData.isUseLocalConfigInfo() && path.exists()) {
- String content = LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant);
- String md5 = MD5.getInstance().getMD5String(content);
- cacheData.setUseLocalConfigInfo(true);
- cacheData.setLocalConfigInfoVersion(path.lastModified());
- cacheData.setContent(content);
+ HttpResult result = null;
+ try {
+ List params = null;
+ if (StringUtils.isBlank(tenant)) {
+ params = Arrays.asList("dataId", dataId, "group", group);
+ } else {
+ params = Arrays.asList("dataId", dataId, "group", group, "tenant", tenant);
+ }
+ result = agent.httpGet(Constants.CONFIG_CONTROLLER_PATH, null, params, agent.getEncode(), readTimeout);
+ } catch (IOException e) {
+ log.error(agent.getName(), "NACOS-XXXX",
+ "[sub-server] get server config exception, dataId={}, group={}, tenant={}, msg={}", dataId, group,
+ tenant, e.toString());
+ throw new NacosException(NacosException.SERVER_ERROR, e.getMessage());
+ }
- log.warn(agent.getName(),
- "[failover-change] failover file created. dataId={}, group={}, tenant={}, md5={}, content={}",
- dataId, group, tenant, md5, ContentUtils.truncateContent(content));
- return;
- }
+ switch (result.code) {
+ case HttpURLConnection.HTTP_OK:
+ LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, result.content);
+ return result.content;
+ case HttpURLConnection.HTTP_NOT_FOUND:
+ LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, null);
+ return null;
+ case HttpURLConnection.HTTP_CONFLICT: {
+ log.error(agent.getName(), "NACOS-XXXX",
+ "[sub-server-error] get server config being modified concurrently, dataId={}, group={}, tenant={}",
+ dataId, group, tenant);
+ throw new NacosException(NacosException.CONFLICT,
+ "data being modified, dataId=" + dataId + ",group=" + group + ",tenant=" + tenant);
+ }
+ case HttpURLConnection.HTTP_FORBIDDEN: {
+ log.error(agent.getName(), "NACOS-XXXX", "[sub-server-error] no right, dataId={}, group={}, tenant={}",
+ dataId, group, tenant);
+ throw new NacosException(result.code, result.content);
+ }
+ default: {
+ log.error(agent.getName(), "NACOS-XXXX", "[sub-server-error] dataId={}, group={}, tenant={}, code={}",
+ dataId, group, tenant, result.code);
+ throw new NacosException(result.code,
+ "http error, code=" + result.code + ",dataId=" + dataId + ",group=" + group + ",tenant=" + tenant);
+ }
+ }
+ }
- // 有 -> 没有。不通知业务监听器,从server拿到配置后通知。
- if (cacheData.isUseLocalConfigInfo() && !path.exists()) {
- cacheData.setUseLocalConfigInfo(false);
- log.warn(agent.getName(), "[failover-change] failover file deleted. dataId={}, group={}, tenant={}", dataId,
- group, tenant);
- return;
- }
+ private void checkLocalConfig(CacheData cacheData) {
+ final String dataId = cacheData.dataId;
+ final String group = cacheData.group;
+ final String tenant = cacheData.tenant;
+ File path = LocalConfigInfoProcessor.getFailoverFile(agent.getName(), dataId, group, tenant);
+
+ // 没有 -> 有
+ if (!cacheData.isUseLocalConfigInfo() && path.exists()) {
+ String content = LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant);
+ String md5 = MD5.getInstance().getMD5String(content);
+ cacheData.setUseLocalConfigInfo(true);
+ cacheData.setLocalConfigInfoVersion(path.lastModified());
+ cacheData.setContent(content);
+
+ log.warn(agent.getName(),
+ "[failover-change] failover file created. dataId={}, group={}, tenant={}, md5={}, content={}",
+ dataId, group, tenant, md5, ContentUtils.truncateContent(content));
+ return;
+ }
+
+ // 有 -> 没有。不通知业务监听器,从server拿到配置后通知。
+ if (cacheData.isUseLocalConfigInfo() && !path.exists()) {
+ cacheData.setUseLocalConfigInfo(false);
+ log.warn(agent.getName(), "[failover-change] failover file deleted. dataId={}, group={}, tenant={}", dataId,
+ group, tenant);
+ return;
+ }
+
+ // 有变更
+ if (cacheData.isUseLocalConfigInfo() && path.exists()
+ && cacheData.getLocalConfigInfoVersion() != path.lastModified()) {
+ String content = LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant);
+ String md5 = MD5.getInstance().getMD5String(content);
+ cacheData.setUseLocalConfigInfo(true);
+ cacheData.setLocalConfigInfoVersion(path.lastModified());
+ cacheData.setContent(content);
+ log.warn(agent.getName(),
+ "[failover-change] failover file changed. dataId={}, group={}, tenant={}, md5={}, content={}",
+ dataId, group, tenant, md5, ContentUtils.truncateContent(content));
+ return;
+ }
+ }
- // 有变更
- if (cacheData.isUseLocalConfigInfo() && path.exists()
- && cacheData.getLocalConfigInfoVersion() != path.lastModified()) {
- String content = LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant);
- String md5 = MD5.getInstance().getMD5String(content);
- cacheData.setUseLocalConfigInfo(true);
- cacheData.setLocalConfigInfoVersion(path.lastModified());
- cacheData.setContent(content);
- log.warn(agent.getName(),
- "[failover-change] failover file changed. dataId={}, group={}, tenant={}, md5={}, content={}",
- dataId, group, tenant, md5, ContentUtils.truncateContent(content));
- return;
- }
- }
-
private String null2defaultGroup(String group) {
return (null == group) ? Constants.DEFAULT_GROUP : group.trim();
}
-
- public void checkConfigInfo() {
- // 分任务
- int listenerSize = cacheMap.get().size();
- // 向上取整为批数
- int longingTaskCount = (int) Math.ceil(listenerSize / ParamUtil.getPerTaskConfigSize());
- if (longingTaskCount > currentLongingTaskCount) {
- for (int i = (int) currentLongingTaskCount; i < longingTaskCount; i++) {
- // 要判断任务是否在执行 这块需要好好想想。 任务列表现在是无序的。变化过程可能有问题
- executorService.execute(new LongPullingRunnable(i));
- }
- currentLongingTaskCount = longingTaskCount;
- }
- }
- /**
- * 从Server获取值变化了的DataID列表。返回的对象里只有dataId和group是有效的。 保证不返回NULL。
- */
- List checkUpdateDataIds(List cacheDatas, List inInitializingCacheList) {
- StringBuilder sb = new StringBuilder();
- for (CacheData cacheData : cacheDatas) {
- if (!cacheData.isUseLocalConfigInfo()) {
- sb.append(cacheData.dataId).append(WORD_SEPARATOR);
- sb.append(cacheData.group).append(WORD_SEPARATOR);
- if (StringUtils.isBlank(cacheData.tenant)) {
- sb.append(cacheData.getMd5()).append(LINE_SEPARATOR);
- } else {
- sb.append(cacheData.getMd5()).append(WORD_SEPARATOR);
- sb.append(cacheData.getTenant()).append(LINE_SEPARATOR);
- }
- if (cacheData.isInitializing()) {
- // cacheData 首次出现在cacheMap中&首次check更新
- inInitializingCacheList
- .add(GroupKey.getKeyTenant(cacheData.dataId, cacheData.group, cacheData.tenant));
- }
- }
- }
- boolean isInitializingCacheList = !inInitializingCacheList.isEmpty();
- return checkUpdateConfigStr(sb.toString(), isInitializingCacheList);
- }
+ public void checkConfigInfo() {
+ // 分任务
+ int listenerSize = cacheMap.get().size();
+ // 向上取整为批数
+ int longingTaskCount = (int)Math.ceil(listenerSize / ParamUtil.getPerTaskConfigSize());
+ if (longingTaskCount > currentLongingTaskCount) {
+ for (int i = (int)currentLongingTaskCount; i < longingTaskCount; i++) {
+ // 要判断任务是否在执行 这块需要好好想想。 任务列表现在是无序的。变化过程可能有问题
+ executorService.execute(new LongPullingRunnable(i));
+ }
+ currentLongingTaskCount = longingTaskCount;
+ }
+ }
- /**
- * 从Server获取值变化了的DataID列表。返回的对象里只有dataId和group是有效的。 保证不返回NULL。
- */
- List checkUpdateConfigStr(String probeUpdateString, boolean isInitializingCacheList) {
+ /**
+ * 从Server获取值变化了的DataID列表。返回的对象里只有dataId和group是有效的。 保证不返回NULL。
+ */
+ List checkUpdateDataIds(List cacheDatas, List inInitializingCacheList) {
+ StringBuilder sb = new StringBuilder();
+ for (CacheData cacheData : cacheDatas) {
+ if (!cacheData.isUseLocalConfigInfo()) {
+ sb.append(cacheData.dataId).append(WORD_SEPARATOR);
+ sb.append(cacheData.group).append(WORD_SEPARATOR);
+ if (StringUtils.isBlank(cacheData.tenant)) {
+ sb.append(cacheData.getMd5()).append(LINE_SEPARATOR);
+ } else {
+ sb.append(cacheData.getMd5()).append(WORD_SEPARATOR);
+ sb.append(cacheData.getTenant()).append(LINE_SEPARATOR);
+ }
+ if (cacheData.isInitializing()) {
+ // cacheData 首次出现在cacheMap中&首次check更新
+ inInitializingCacheList
+ .add(GroupKey.getKeyTenant(cacheData.dataId, cacheData.group, cacheData.tenant));
+ }
+ }
+ }
+ boolean isInitializingCacheList = !inInitializingCacheList.isEmpty();
+ return checkUpdateConfigStr(sb.toString(), isInitializingCacheList);
+ }
- List params = Arrays.asList(Constants.PROBE_MODIFY_REQUEST, probeUpdateString);
- long timeout = TimeUnit.SECONDS.toMillis(30L);
+ /**
+ * 从Server获取值变化了的DataID列表。返回的对象里只有dataId和group是有效的。 保证不返回NULL。
+ */
+ List checkUpdateConfigStr(String probeUpdateString, boolean isInitializingCacheList) {
- List headers = new ArrayList(2);
- headers.add("Long-Pulling-Timeout");
- headers.add("" + timeout);
+ List params = Arrays.asList(Constants.PROBE_MODIFY_REQUEST, probeUpdateString);
+ long timeout = TimeUnit.SECONDS.toMillis(30L);
- // told server do not hang me up if new initializing cacheData added in
- if (isInitializingCacheList) {
- headers.add("Long-Pulling-Timeout-No-Hangup");
- headers.add("true");
- }
+ List headers = new ArrayList(2);
+ headers.add("Long-Pulling-Timeout");
+ headers.add("" + timeout);
- if (StringUtils.isBlank(probeUpdateString)) {
- return Collections.emptyList();
- }
+ // told server do not hang me up if new initializing cacheData added in
+ if (isInitializingCacheList) {
+ headers.add("Long-Pulling-Timeout-No-Hangup");
+ headers.add("true");
+ }
- try {
- HttpResult result = agent.httpPost(Constants.CONFIG_CONTROLLER_PATH + "/listener", headers, params,
- agent.getEncode(), timeout);
+ if (StringUtils.isBlank(probeUpdateString)) {
+ return Collections.emptyList();
+ }
- if (HttpURLConnection.HTTP_OK == result.code) {
- setHealthServer(true);
- return parseUpdateDataIdResponse(result.content);
- } else {
- setHealthServer(false);
- if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR) {
- log.error("NACOS-0007", LoggerHelper.getErrorCodeStr("Nacos", "Nacos-0007", "环境问题",
- "[check-update] get changed dataId error"));
- }
- log.error(agent.getName(), "NACOS-XXXX", "[check-update] get changed dataId error, code={}",
- result.code);
- }
- } catch (IOException e) {
- setHealthServer(false);
- log.error(agent.getName(), "NACOS-XXXX", "[check-update] get changed dataId exception, msg={}",
- e.toString());
- }
- return Collections.emptyList();
- }
+ try {
+ HttpResult result = agent.httpPost(Constants.CONFIG_CONTROLLER_PATH + "/listener", headers, params,
+ agent.getEncode(), timeout);
- /**
- * 从HTTP响应拿到变化的groupKey。保证不返回NULL。
- */
- private List parseUpdateDataIdResponse(String response) {
- if (StringUtils.isBlank(response)) {
- return Collections.emptyList();
- }
+ if (HttpURLConnection.HTTP_OK == result.code) {
+ setHealthServer(true);
+ return parseUpdateDataIdResponse(result.content);
+ } else {
+ setHealthServer(false);
+ if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR) {
+ log.error("NACOS-0007", LoggerHelper.getErrorCodeStr("Nacos", "Nacos-0007", "环境问题",
+ "[check-update] get changed dataId error"));
+ }
+ log.error(agent.getName(), "NACOS-XXXX", "[check-update] get changed dataId error, code={}",
+ result.code);
+ }
+ } catch (IOException e) {
+ setHealthServer(false);
+ log.error(agent.getName(), "NACOS-XXXX", "[check-update] get changed dataId exception, msg={}",
+ e.toString());
+ }
+ return Collections.emptyList();
+ }
- try {
- response = URLDecoder.decode(response, "UTF-8");
- } catch (Exception e) {
- log.error(agent.getName(), "NACOS-XXXX", "[polling-resp] decode modifiedDataIdsString error", e);
- }
+ /**
+ * 从HTTP响应拿到变化的groupKey。保证不返回NULL。
+ */
+ private List parseUpdateDataIdResponse(String response) {
+ if (StringUtils.isBlank(response)) {
+ return Collections.emptyList();
+ }
- List updateList = new LinkedList();
+ try {
+ response = URLDecoder.decode(response, "UTF-8");
+ } catch (Exception e) {
+ log.error(agent.getName(), "NACOS-XXXX", "[polling-resp] decode modifiedDataIdsString error", e);
+ }
- for (String dataIdAndGroup : response.split(LINE_SEPARATOR)) {
- if (!StringUtils.isBlank(dataIdAndGroup)) {
- String[] keyArr = dataIdAndGroup.split(WORD_SEPARATOR);
- String dataId = keyArr[0];
- String group = keyArr[1];
- if (keyArr.length == 2) {
- updateList.add(GroupKey.getKey(dataId, group));
- log.info(agent.getName(), "[polling-resp] config changed. dataId={}, group={}", dataId, group);
- } else if (keyArr.length == 3) {
- String tenant = keyArr[2];
- updateList.add(GroupKey.getKeyTenant(dataId, group, tenant));
- log.info(agent.getName(), "[polling-resp] config changed. dataId={}, group={}, tenant={}", dataId,
- group, tenant);
- } else {
- log.error(agent.getName(), "NACOS-XXXX", "[polling-resp] invalid dataIdAndGroup error",
- dataIdAndGroup);
- }
- }
- }
- return updateList;
- }
+ List updateList = new LinkedList();
- @SuppressWarnings("PMD.ThreadPoolCreationRule")
- public ClientWorker(final ServerHttpAgent agent, final ConfigFilterChainManager configFilterChainManager) {
- this.agent = agent;
- this.configFilterChainManager = configFilterChainManager;
- executor = Executors.newScheduledThreadPool(1, new ThreadFactory() {
- @Override
- public Thread newThread(Runnable r) {
- Thread t = new Thread(r);
- t.setName("com.alibaba.nacos.client.Worker." + agent.getName());
- t.setDaemon(true);
- return t;
- }
- });
+ for (String dataIdAndGroup : response.split(LINE_SEPARATOR)) {
+ if (!StringUtils.isBlank(dataIdAndGroup)) {
+ String[] keyArr = dataIdAndGroup.split(WORD_SEPARATOR);
+ String dataId = keyArr[0];
+ String group = keyArr[1];
+ if (keyArr.length == 2) {
+ updateList.add(GroupKey.getKey(dataId, group));
+ log.info(agent.getName(), "[polling-resp] config changed. dataId={}, group={}", dataId, group);
+ } else if (keyArr.length == 3) {
+ String tenant = keyArr[2];
+ updateList.add(GroupKey.getKeyTenant(dataId, group, tenant));
+ log.info(agent.getName(), "[polling-resp] config changed. dataId={}, group={}, tenant={}", dataId,
+ group, tenant);
+ } else {
+ log.error(agent.getName(), "NACOS-XXXX", "[polling-resp] invalid dataIdAndGroup error",
+ dataIdAndGroup);
+ }
+ }
+ }
+ return updateList;
+ }
- executorService = Executors.newCachedThreadPool(new ThreadFactory() {
- @Override
- public Thread newThread(Runnable r) {
- Thread t = new Thread(r);
- t.setName("com.alibaba.nacos.client.Worker.longPulling" + agent.getName());
- t.setDaemon(true);
- return t;
- }
- });
+ @SuppressWarnings("PMD.ThreadPoolCreationRule")
+ public ClientWorker(final ServerHttpAgent agent, final ConfigFilterChainManager configFilterChainManager) {
+ this.agent = agent;
+ this.configFilterChainManager = configFilterChainManager;
+ executor = Executors.newScheduledThreadPool(1, new ThreadFactory() {
+ @Override
+ public Thread newThread(Runnable r) {
+ Thread t = new Thread(r);
+ t.setName("com.alibaba.nacos.client.Worker." + agent.getName());
+ t.setDaemon(true);
+ return t;
+ }
+ });
- executor.scheduleWithFixedDelay(new Runnable() {
- public void run() {
- try {
- checkConfigInfo();
- } catch (Throwable e) {
- log.error(agent.getName(), "NACOS-XXXX", "[sub-check] rotate check error", e);
- }
- }
- }, 1L, 10L, TimeUnit.MILLISECONDS);
- }
+ executorService = Executors.newCachedThreadPool(new ThreadFactory() {
+ @Override
+ public Thread newThread(Runnable r) {
+ Thread t = new Thread(r);
+ t.setName("com.alibaba.nacos.client.Worker.longPulling" + agent.getName());
+ t.setDaemon(true);
+ return t;
+ }
+ });
- class LongPullingRunnable implements Runnable {
- private int taskId;
+ executor.scheduleWithFixedDelay(new Runnable() {
+ public void run() {
+ try {
+ checkConfigInfo();
+ } catch (Throwable e) {
+ log.error(agent.getName(), "NACOS-XXXX", "[sub-check] rotate check error", e);
+ }
+ }
+ }, 1L, 10L, TimeUnit.MILLISECONDS);
+ }
- public LongPullingRunnable(int taskId) {
- this.taskId = taskId;
- }
+ class LongPullingRunnable implements Runnable {
+ private int taskId;
- public void run() {
- try {
- List cacheDatas = new ArrayList();
- // check failover config
- for (CacheData cacheData : cacheMap.get().values()) {
- if (cacheData.getTaskId() == taskId) {
- cacheDatas.add(cacheData);
- try {
- checkLocalConfig(cacheData);
- if (cacheData.isUseLocalConfigInfo()) {
- cacheData.checkListenerMd5();
- }
- } catch (Exception e) {
- log.error("NACOS-CLIENT", "get local config info error", e);
- }
- }
- }
+ public LongPullingRunnable(int taskId) {
+ this.taskId = taskId;
+ }
- List inInitializingCacheList = new ArrayList();
- // check server config
- List changedGroupKeys = checkUpdateDataIds(cacheDatas, inInitializingCacheList);
+ public void run() {
+ try {
+ List cacheDatas = new ArrayList();
+ // check failover config
+ for (CacheData cacheData : cacheMap.get().values()) {
+ if (cacheData.getTaskId() == taskId) {
+ cacheDatas.add(cacheData);
+ try {
+ checkLocalConfig(cacheData);
+ if (cacheData.isUseLocalConfigInfo()) {
+ cacheData.checkListenerMd5();
+ }
+ } catch (Exception e) {
+ log.error("NACOS-CLIENT", "get local config info error", e);
+ }
+ }
+ }
- for (String groupKey : changedGroupKeys) {
- String[] key = GroupKey.parseKey(groupKey);
- String dataId = key[0];
- String group = key[1];
- String tenant = null;
- if (key.length == 3) {
- tenant = key[2];
- }
- try {
- String content = getServerConfig(dataId, group, tenant, 3000L);
- CacheData cache = cacheMap.get().get(GroupKey.getKeyTenant(dataId, group, tenant));
- cache.setContent(content);
- log.info(agent.getName(), "[data-received] dataId={}, group={}, tenant={}, md5={}, content={}",
- dataId, group, tenant, cache.getMd5(), ContentUtils.truncateContent(content));
- } catch (NacosException ioe) {
- log.error(agent.getName(), "NACOS-XXXX",
- "[get-update] get changed config exception. dataId={}, group={}, tenant={}, msg={}",
- dataId, group, tenant, ioe.toString());
- }
- }
- for (CacheData cacheData : cacheDatas) {
- if (!cacheData.isInitializing() || inInitializingCacheList
- .contains(GroupKey.getKeyTenant(cacheData.dataId, cacheData.group, cacheData.tenant))) {
- cacheData.checkListenerMd5();
- cacheData.setInitializing(false);
- }
- }
- inInitializingCacheList.clear();
- } catch (Throwable e) {
- log.error("500", "longPulling error", e);
- } finally {
- executorService.execute(this);
- }
- }
- }
+ List inInitializingCacheList = new ArrayList();
+ // check server config
+ List changedGroupKeys = checkUpdateDataIds(cacheDatas, inInitializingCacheList);
- // =================
+ for (String groupKey : changedGroupKeys) {
+ String[] key = GroupKey.parseKey(groupKey);
+ String dataId = key[0];
+ String group = key[1];
+ String tenant = null;
+ if (key.length == 3) {
+ tenant = key[2];
+ }
+ try {
+ String content = getServerConfig(dataId, group, tenant, 3000L);
+ CacheData cache = cacheMap.get().get(GroupKey.getKeyTenant(dataId, group, tenant));
+ cache.setContent(content);
+ log.info(agent.getName(), "[data-received] dataId={}, group={}, tenant={}, md5={}, content={}",
+ dataId, group, tenant, cache.getMd5(), ContentUtils.truncateContent(content));
+ } catch (NacosException ioe) {
+ log.error(agent.getName(), "NACOS-XXXX",
+ "[get-update] get changed config exception. dataId={}, group={}, tenant={}, msg={}",
+ dataId, group, tenant, ioe.toString());
+ }
+ }
+ for (CacheData cacheData : cacheDatas) {
+ if (!cacheData.isInitializing() || inInitializingCacheList
+ .contains(GroupKey.getKeyTenant(cacheData.dataId, cacheData.group, cacheData.tenant))) {
+ cacheData.checkListenerMd5();
+ cacheData.setInitializing(false);
+ }
+ }
+ inInitializingCacheList.clear();
+ } catch (Throwable e) {
+ log.error("500", "longPulling error", e);
+ } finally {
+ executorService.execute(this);
+ }
+ }
+ }
- public boolean isHealthServer() {
- return isHealthServer;
- }
+ // =================
- private void setHealthServer(boolean isHealthServer) {
- this.isHealthServer = isHealthServer;
- }
+ public boolean isHealthServer() {
+ return isHealthServer;
+ }
+
+ private void setHealthServer(boolean isHealthServer) {
+ this.isHealthServer = isHealthServer;
+ }
+
+ final ScheduledExecutorService executor;
+ final ExecutorService executorService;
+ /**
+ * groupKey -> cacheData
+ */
+ AtomicReference
-*
-* Since this class operates directly on byte streams, and not character streams, it is hard-coded to only encode/decode
-* character encodings which are compatible with the lower 127 ASCII chart (ISO-8859-1, Windows-1252, UTF-8, etc).
-*
-*
-* This class is not thread-safe. Each thread should use its own instance.
-*
-*
-* @see RFC 2045
-* @author Apache Software Foundation
-* @since 1.0
-* @version $Revision: 1080712 $
-*/
+ * Provides Base64 encoding and decoding as defined by RFC 2045.
+ *
+ *
This class implements section 6.8. Base64 Content-Transfer-Encoding from RFC 2045 Multipurpose
+ * Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies by Freed and Borenstein.
+ * The class can be parameterized in the following manner with various constructors:
URL-safe mode: Default
+ * off.
Line length: Default 76. Line length that aren't multiples of 4 will still essentially end up being
+ * multiples of 4 in the encoded data.
Line separator: Default is CRLF ("\r\n")
Since this class
+ * operates directly on byte streams, and not character streams, it is hard-coded to only encode/decode character
+ * encodings which are compatible with the lower 127 ASCII chart (ISO-8859-1, Windows-1252, UTF-8, etc).
This
+ * class is not thread-safe. Each thread should use its own instance.
+ *
+ * @author Apache Software Foundation
+ * @version $Revision: 1080712 $
+ * @see RFC 2045
+ * @since 1.0
+ */
public class Base64 {
- /**
- * BASE32 characters are 6 bits in length.
- * They are formed by taking a block of 3 octets to form a 24-bit string,
- * which is converted into 4 BASE64 characters.
- */
- private static final int BITS_PER_ENCODED_BYTE = 6;
- private static final int BYTES_PER_UNENCODED_BLOCK = 3;
- private static final int BYTES_PER_ENCODED_BLOCK = 4;
+ /**
+ * BASE32 characters are 6 bits in length. They are formed by taking a block of 3 octets to form a 24-bit string,
+ * which is converted into 4 BASE64 characters.
+ */
+ private static final int BITS_PER_ENCODED_BYTE = 6;
+ private static final int BYTES_PER_UNENCODED_BLOCK = 3;
+ private static final int BYTES_PER_ENCODED_BLOCK = 4;
- /**
- * Chunk separator per RFC 2045 section 2.1.
- *
- *
- * N.B. The next major release may break compatibility and make this field private.
- *
N.B. The next major release may break compatibility and make this field private.
+ *
+ * @see RFC 2045 section 2.1
+ */
+ static final byte[] CHUNK_SEPARATOR = {'\r', '\n'};
- /**
- * This array is a lookup table that translates 6-bit positive integer index values into their "Base64 Alphabet"
- * equivalents as specified in Table 1 of RFC 2045.
- *
- * Thanks to "commons" project in ws.apache.org for this code.
- * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
- */
- private static final byte[] STANDARD_ENCODE_TABLE = {
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
- 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
- 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
- };
+ /**
+ * This array is a lookup table that translates 6-bit positive integer index values into their "Base64 Alphabet"
+ * equivalents as specified in Table 1 of RFC 2045.
+ *
+ * Thanks to "commons" project in ws.apache.org for this code. http://svn.apache
+ * .org/repos/asf/webservices/commons/trunk/modules/util/
+ */
+ private static final byte[] STANDARD_ENCODE_TABLE = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+ 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+ 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
+ };
- /**
- * This is a copy of the STANDARD_ENCODE_TABLE above, but with + and /
- * changed to - and _ to make the encoded Base64 results more URL-SAFE.
- * This table is only used when the Base64's mode is set to URL-SAFE.
- */
- private static final byte[] URL_SAFE_ENCODE_TABLE = {
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
- 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
- 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'
- };
+ /**
+ * This is a copy of the STANDARD_ENCODE_TABLE above, but with + and / changed to - and _ to make the encoded Base64
+ * results more URL-SAFE. This table is only used when the Base64's mode is set to URL-SAFE.
+ */
+ private static final byte[] URL_SAFE_ENCODE_TABLE = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+ 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+ 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'
+ };
- /**
- * This array is a lookup table that translates Unicode characters drawn from the "Base64 Alphabet" (as specified in
- * Table 1 of RFC 2045) into their 6-bit positive integer equivalents. Characters that are not in the Base64
- * alphabet but fall within the bounds of the array are translated to -1.
- *
- * Note: '+' and '-' both decode to 62. '/' and '_' both decode to 63. This means decoder seamlessly handles both
- * URL_SAFE and STANDARD base64. (The encoder, on the other hand, needs to know ahead of time what to emit).
- *
- * Thanks to "commons" project in ws.apache.org for this code.
- * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
- */
- private static final byte[] DECODE_TABLE = {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, 52, 53, 54,
- 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4,
- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, -1, -1, -1, -1, 63, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34,
- 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
- };
+ /**
+ * This array is a lookup table that translates Unicode characters drawn from the "Base64 Alphabet" (as specified in
+ * Table 1 of RFC 2045) into their 6-bit positive integer equivalents. Characters that are not in the Base64
+ * alphabet but fall within the bounds of the array are translated to -1.
+ *
+ * Note: '+' and '-' both decode to 62. '/' and '_' both decode to 63. This means decoder seamlessly handles both
+ * URL_SAFE and STANDARD base64. (The encoder, on the other hand, needs to know ahead of time what to emit).
+ *
+ * Thanks to "commons" project in ws.apache.org for this code. http://svn.apache
+ * .org/repos/asf/webservices/commons/trunk/modules/util/
+ */
+ private static final byte[] DECODE_TABLE = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, -1, -1, -1, -1, 63, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
+ };
- /**
- * Base64 uses 6-bit fields.
- */
- /** Mask used to extract 6 bits, used when encoding */
- private static final int MASK_6BITS = 0x3f;
+ /**
+ * Base64 uses 6-bit fields.
+ */
+ /**
+ * Mask used to extract 6 bits, used when encoding
+ */
+ private static final int MASK_6BITS = 0x3f;
- // The static final fields above are used for the original static byte[] methods on Base64.
- // The private member fields below are used with the new streaming approach, which requires
- // some state be preserved between calls of encode() and decode().
+ // The static final fields above are used for the original static byte[] methods on Base64.
+ // The private member fields below are used with the new streaming approach, which requires
+ // some state be preserved between calls of encode() and decode().
- /**
- * Encode table to use: either STANDARD or URL_SAFE. Note: the DECODE_TABLE above remains static because it is able
- * to decode both STANDARD and URL_SAFE streams, but the encodeTable must be a member variable so we can switch
- * between the two modes.
- */
- private final byte[] encodeTable;
+ /**
+ * Encode table to use: either STANDARD or URL_SAFE. Note: the DECODE_TABLE above remains static because it is able
+ * to decode both STANDARD and URL_SAFE streams, but the encodeTable must be a member variable so we can switch
+ * between the two modes.
+ */
+ private final byte[] encodeTable;
- /**
- * Only one decode table currently; keep for consistency with Base32 code
- */
- private final byte[] decodeTable = DECODE_TABLE;
+ /**
+ * Only one decode table currently; keep for consistency with Base32 code
+ */
+ private final byte[] decodeTable = DECODE_TABLE;
- /**
- * Line separator for encoding. Not used when decoding. Only used if lineLength > 0.
- */
- private final byte[] lineSeparator;
+ /**
+ * Line separator for encoding. Not used when decoding. Only used if lineLength > 0.
+ */
+ private final byte[] lineSeparator;
- /**
- * Convenience variable to help us determine when our buffer is going to run out of room and needs resizing.
- * decodeSize = 3 + lineSeparator.length;
- */
- private final int decodeSize;
+ /**
+ * Convenience variable to help us determine when our buffer is going to run out of room and needs resizing.
+ * decodeSize = 3 + lineSeparator.length;
+ */
+ private final int decodeSize;
- /**
- * Convenience variable to help us determine when our buffer is going to run out of room and needs resizing.
- * encodeSize = 4 + lineSeparator.length;
- */
- private final int encodeSize;
+ /**
+ * Convenience variable to help us determine when our buffer is going to run out of room and needs resizing.
+ * encodeSize = 4 + lineSeparator.length;
+ */
+ private final int encodeSize;
- /**
- * Place holder for the bytes we're dealing with for our based logic.
- * Bitwise operations store and extract the encoding or decoding from this variable.
- */
- private int bitWorkArea;
+ /**
+ * Place holder for the bytes we're dealing with for our based logic. Bitwise operations store and extract the
+ * encoding or decoding from this variable.
+ */
+ private int bitWorkArea;
- /**
- * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode.
- *
- * When encoding the line length is 0 (no chunking), and the encoding table is STANDARD_ENCODE_TABLE.
- *
- *
- *
- * When decoding all variants are supported.
- *
- */
- public Base64() {
- this(0, CHUNK_SEPARATOR, false);
- }
+ /**
+ * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode.
When encoding the line
+ * length is 0 (no chunking), and the encoding table is STANDARD_ENCODE_TABLE.
+ *
+ *
When decoding all variants are supported.
+ */
+ public Base64() {
+ this(0, CHUNK_SEPARATOR, false);
+ }
- /**
- * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode.
- *
- * When encoding the line length and line separator are given in the constructor, and the encoding table is
- * STANDARD_ENCODE_TABLE.
- *
- *
- * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data.
- *
- *
- * When decoding all variants are supported.
- *
- *
- * @param lineLength
- * Each line of encoded data will be at most of the given length (rounded down to nearest multiple of 4).
- * If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when decoding.
- * @param lineSeparator
- * Each line of encoded data will end with this sequence of bytes.
- * @param urlSafe
- * Instead of emitting '+' and '/' we emit '-' and '_' respectively. urlSafe is only applied to encode
- * operations. Decoding seamlessly handles both modes.
- * @throws IllegalArgumentException
- * The provided lineSeparator included some base64 characters. That's not going to work!
- * @since 1.4
- */
- public Base64(int lineLength, byte[] lineSeparator, boolean urlSafe) {
- chunkSeparatorLength = lineSeparator == null ? 0 : lineSeparator.length;
- unencodedBlockSize = BYTES_PER_UNENCODED_BLOCK;
- encodedBlockSize = BYTES_PER_ENCODED_BLOCK;
- this.lineLength = (lineLength > 0 && chunkSeparatorLength > 0) ? (lineLength / encodedBlockSize) * encodedBlockSize : 0;
- // TODO could be simplified if there is no requirement to reject invalid line sep when length <=0
- // @see test case Base64Test.testConstructors()
- if (lineSeparator != null) {
- if (containsAlphabetOrPad(lineSeparator)) {
- String sep = null;
- try {
- sep = new String(lineSeparator, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- }
- throw new IllegalArgumentException("lineSeparator must not contain base64 characters: [" + sep + "]");
- }
- if (lineLength > 0){
- this.encodeSize = BYTES_PER_ENCODED_BLOCK + lineSeparator.length;
- this.lineSeparator = new byte[lineSeparator.length];
- System.arraycopy(lineSeparator, 0, this.lineSeparator, 0, lineSeparator.length);
- } else {
- this.encodeSize = BYTES_PER_ENCODED_BLOCK;
- this.lineSeparator = null;
- }
- } else {
- this.encodeSize = BYTES_PER_ENCODED_BLOCK;
- this.lineSeparator = null;
- }
- this.decodeSize = this.encodeSize - 1;
- this.encodeTable = urlSafe ? URL_SAFE_ENCODE_TABLE : STANDARD_ENCODE_TABLE;
- }
+ /**
+ * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode.
When encoding the line
+ * length and line separator are given in the constructor, and the encoding table is STANDARD_ENCODE_TABLE.
+ * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data.
+ *
When decoding all variants are supported.
+ *
+ * @param lineLength Each line of encoded data will be at most of the given length (rounded down to nearest
+ * multiple of 4). If lineLength <= 0, then the output will not be divided into lines (chunks).
+ * Ignored when decoding.
+ * @param lineSeparator Each line of encoded data will end with this sequence of bytes.
+ * @param urlSafe Instead of emitting '+' and '/' we emit '-' and '_' respectively. urlSafe is only applied to
+ * encode operations. Decoding seamlessly handles both modes.
+ * @throws IllegalArgumentException The provided lineSeparator included some base64 characters. That's not going to
+ * work!
+ * @since 1.4
+ */
+ public Base64(int lineLength, byte[] lineSeparator, boolean urlSafe) {
+ chunkSeparatorLength = lineSeparator == null ? 0 : lineSeparator.length;
+ unencodedBlockSize = BYTES_PER_UNENCODED_BLOCK;
+ encodedBlockSize = BYTES_PER_ENCODED_BLOCK;
+ this.lineLength = (lineLength > 0 && chunkSeparatorLength > 0) ? (lineLength / encodedBlockSize)
+ * encodedBlockSize : 0;
+ // TODO could be simplified if there is no requirement to reject invalid line sep when length <=0
+ // @see test case Base64Test.testConstructors()
+ if (lineSeparator != null) {
+ if (containsAlphabetOrPad(lineSeparator)) {
+ String sep = null;
+ try {
+ sep = new String(lineSeparator, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ }
+ throw new IllegalArgumentException("lineSeparator must not contain base64 characters: [" + sep + "]");
+ }
+ if (lineLength > 0) {
+ this.encodeSize = BYTES_PER_ENCODED_BLOCK + lineSeparator.length;
+ this.lineSeparator = new byte[lineSeparator.length];
+ System.arraycopy(lineSeparator, 0, this.lineSeparator, 0, lineSeparator.length);
+ } else {
+ this.encodeSize = BYTES_PER_ENCODED_BLOCK;
+ this.lineSeparator = null;
+ }
+ } else {
+ this.encodeSize = BYTES_PER_ENCODED_BLOCK;
+ this.lineSeparator = null;
+ }
+ this.decodeSize = this.encodeSize - 1;
+ this.encodeTable = urlSafe ? URL_SAFE_ENCODE_TABLE : STANDARD_ENCODE_TABLE;
+ }
- /**
- *
- * Encodes all of the provided data, starting at inPos, for inAvail bytes. Must be called at least twice: once with
- * the data to encode, and once with inAvail set to "-1" to alert encoder that EOF has been reached, so flush last
- * remaining bytes (if not multiple of 3).
- *
- *
- * Thanks to "commons" project in ws.apache.org for the bitwise operations, and general approach.
- * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
- *
- *
- * @param in
- * byte[] array of binary data to base64 encode.
- * @param inPos
- * Position to start reading data from.
- * @param inAvail
- * Amount of bytes available from input for encoding.
- */
- void encode(byte[] in, int inPos, int inAvail) {
- if (eof) {
- return;
- }
- if (inAvail < 0) {
- eof = true;
- if (0 == modulus && lineLength == 0) {
- return;
- }
- ensureBufferSize(encodeSize);
- int savedPos = pos;
- switch (modulus) {
- case 1 :
- buffer[pos++] = encodeTable[(bitWorkArea >> 2) & MASK_6BITS];
- buffer[pos++] = encodeTable[(bitWorkArea << 4) & MASK_6BITS];
-
- if (encodeTable == STANDARD_ENCODE_TABLE) {
- buffer[pos++] = PAD;
- buffer[pos++] = PAD;
- }
- break;
+ /**
+ *
Encodes all of the provided data, starting at inPos, for inAvail bytes. Must be called at least twice: once
+ * with the data to encode, and once with inAvail set to "-1" to alert encoder that EOF has been reached, so flush
+ * last remaining bytes (if not multiple of 3).
Thanks to "commons" project in ws.apache.org for the
+ * bitwise operations, and general approach. http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
+ *
+ *
+ * @param in byte[] array of binary data to base64 encode.
+ * @param inPos Position to start reading data from.
+ * @param inAvail Amount of bytes available from input for encoding.
+ */
+ void encode(byte[] in, int inPos, int inAvail) {
+ if (eof) {
+ return;
+ }
+ if (inAvail < 0) {
+ eof = true;
+ if (0 == modulus && lineLength == 0) {
+ return;
+ }
+ ensureBufferSize(encodeSize);
+ int savedPos = pos;
+ switch (modulus) {
+ case 1:
+ buffer[pos++] = encodeTable[(bitWorkArea >> 2) & MASK_6BITS];
+ buffer[pos++] = encodeTable[(bitWorkArea << 4) & MASK_6BITS];
- case 2 :
- buffer[pos++] = encodeTable[(bitWorkArea >> 10) & MASK_6BITS];
- buffer[pos++] = encodeTable[(bitWorkArea >> 4) & MASK_6BITS];
- buffer[pos++] = encodeTable[(bitWorkArea << 2) & MASK_6BITS];
-
- if (encodeTable == STANDARD_ENCODE_TABLE) {
- buffer[pos++] = PAD;
- }
- break;
- default:
- break;
- }
- currentLinePos += pos - savedPos;
- /**
- * if currentPos == 0 we are at the start of a line, so don't add CRLF
- */
- if (lineLength > 0 && currentLinePos > 0) {
- System.arraycopy(lineSeparator, 0, buffer, pos, lineSeparator.length);
- pos += lineSeparator.length;
- }
- } else {
- for (int i = 0; i < inAvail; i++) {
- ensureBufferSize(encodeSize);
- modulus = (modulus+1) % BYTES_PER_UNENCODED_BLOCK;
- int b = in[inPos++];
- if (b < 0) {
- b += 256;
- }
- bitWorkArea = (bitWorkArea << 8) + b;
- if (0 == modulus) {
- buffer[pos++] = encodeTable[(bitWorkArea >> 18) & MASK_6BITS];
- buffer[pos++] = encodeTable[(bitWorkArea >> 12) & MASK_6BITS];
- buffer[pos++] = encodeTable[(bitWorkArea >> 6) & MASK_6BITS];
- buffer[pos++] = encodeTable[bitWorkArea & MASK_6BITS];
- currentLinePos += BYTES_PER_ENCODED_BLOCK;
- if (lineLength > 0 && lineLength <= currentLinePos) {
- System.arraycopy(lineSeparator, 0, buffer, pos, lineSeparator.length);
- pos += lineSeparator.length;
- currentLinePos = 0;
- }
- }
- }
- }
- }
+ if (encodeTable == STANDARD_ENCODE_TABLE) {
+ buffer[pos++] = PAD;
+ buffer[pos++] = PAD;
+ }
+ break;
- /**
- *
- * Decodes all of the provided data, starting at inPos, for inAvail bytes. Should be called at least twice: once
- * with the data to decode, and once with inAvail set to "-1" to alert decoder that EOF has been reached. The "-1"
- * call is not necessary when decoding, but it doesn't hurt, either.
- *
- *
- * Ignores all non-base64 characters. This is how chunked (e.g. 76 character) data is handled, since CR and LF are
- * silently ignored, but has implications for other bytes, too. This method subscribes to the garbage-in,
- * garbage-out philosophy: it will not check the provided data for validity.
- *
- *
- * Thanks to "commons" project in ws.apache.org for the bitwise operations, and general approach.
- * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
- *
- *
- * @param in
- * byte[] array of ascii data to base64 decode.
- * @param inPos
- * Position to start reading data from.
- * @param inAvail
- * Amount of bytes available from input for encoding.
- */
- void decode(byte[] in, int inPos, int inAvail) {
- if (eof) {
- return;
- }
- if (inAvail < 0) {
- eof = true;
- }
- for (int i = 0; i < inAvail; i++) {
- ensureBufferSize(decodeSize);
- byte b = in[inPos++];
- if (b == PAD) {
- // We're done.
- eof = true;
- break;
- } else {
- if (b >= 0 && b < DECODE_TABLE.length) {
- int result = DECODE_TABLE[b];
- if (result >= 0) {
- modulus = (modulus+1) % BYTES_PER_ENCODED_BLOCK;
- bitWorkArea = (bitWorkArea << BITS_PER_ENCODED_BYTE) + result;
- if (modulus == 0) {
- buffer[pos++] = (byte) ((bitWorkArea >> 16) & MASK_8BITS);
- buffer[pos++] = (byte) ((bitWorkArea >> 8) & MASK_8BITS);
- buffer[pos++] = (byte) (bitWorkArea & MASK_8BITS);
- }
- }
- }
- }
- }
+ case 2:
+ buffer[pos++] = encodeTable[(bitWorkArea >> 10) & MASK_6BITS];
+ buffer[pos++] = encodeTable[(bitWorkArea >> 4) & MASK_6BITS];
+ buffer[pos++] = encodeTable[(bitWorkArea << 2) & MASK_6BITS];
- // Two forms of EOF as far as base64 decoder is concerned: actual
- // EOF (-1) and first time '=' character is encountered in stream.
- // This approach makes the '=' padding characters completely optional.
- if (eof && modulus != 0) {
- ensureBufferSize(decodeSize);
-
- // We have some spare bits remaining
- // Output all whole multiples of 8 bits and ignore the rest
- switch (modulus) {
- // case 1: // 6 bits - ignore entirely
- // break;
- case 2 :
- bitWorkArea = bitWorkArea >> 4;
- buffer[pos++] = (byte) ((bitWorkArea) & MASK_8BITS);
- break;
- case 3 :
- bitWorkArea = bitWorkArea >> 2;
- buffer[pos++] = (byte) ((bitWorkArea >> 8) & MASK_8BITS);
- buffer[pos++] = (byte) ((bitWorkArea) & MASK_8BITS);
- break;
- default:
- break;
- }
- }
- }
-
- /**
- * Encodes binary data using the base64 algorithm but does not chunk the output.
- *
- * @param binaryData
- * binary data to encode
- * @return byte[] containing Base64 characters in their UTF-8 representation.
- */
- public static byte[] encodeBase64(byte[] binaryData) {
- return encodeBase64(binaryData, false, false, Integer.MAX_VALUE);
- }
+ if (encodeTable == STANDARD_ENCODE_TABLE) {
+ buffer[pos++] = PAD;
+ }
+ break;
+ default:
+ break;
+ }
+ currentLinePos += pos - savedPos;
+ /**
+ * if currentPos == 0 we are at the start of a line, so don't add CRLF
+ */
+ if (lineLength > 0 && currentLinePos > 0) {
+ System.arraycopy(lineSeparator, 0, buffer, pos, lineSeparator.length);
+ pos += lineSeparator.length;
+ }
+ } else {
+ for (int i = 0; i < inAvail; i++) {
+ ensureBufferSize(encodeSize);
+ modulus = (modulus + 1) % BYTES_PER_UNENCODED_BLOCK;
+ int b = in[inPos++];
+ if (b < 0) {
+ b += 256;
+ }
+ bitWorkArea = (bitWorkArea << 8) + b;
+ if (0 == modulus) {
+ buffer[pos++] = encodeTable[(bitWorkArea >> 18) & MASK_6BITS];
+ buffer[pos++] = encodeTable[(bitWorkArea >> 12) & MASK_6BITS];
+ buffer[pos++] = encodeTable[(bitWorkArea >> 6) & MASK_6BITS];
+ buffer[pos++] = encodeTable[bitWorkArea & MASK_6BITS];
+ currentLinePos += BYTES_PER_ENCODED_BLOCK;
+ if (lineLength > 0 && lineLength <= currentLinePos) {
+ System.arraycopy(lineSeparator, 0, buffer, pos, lineSeparator.length);
+ pos += lineSeparator.length;
+ currentLinePos = 0;
+ }
+ }
+ }
+ }
+ }
- /**
- * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks.
- *
- * @param binaryData
- * Array containing binary data to encode.
- * @param isChunked
- * if true this encoder will chunk the base64 output into 76 character blocks
- * @param urlSafe
- * if true this encoder will emit - and _ instead of the usual + and / characters.
- * @param maxResultSize
- * The maximum result size to accept.
- * @return Base64-encoded data.
- * @throws IllegalArgumentException
- * Thrown when the input array needs an output array bigger than maxResultSize
- * @since 1.4
- */
- public static byte[] encodeBase64(byte[] binaryData, boolean isChunked, boolean urlSafe, int maxResultSize) {
- if (binaryData == null || binaryData.length == 0) {
- return binaryData;
- }
+ /**
+ *
Decodes all of the provided data, starting at inPos, for inAvail bytes. Should be called at least twice: once
+ * with the data to decode, and once with inAvail set to "-1" to alert decoder that EOF has been reached. The "-1"
+ * call is not necessary when decoding, but it doesn't hurt, either.
Ignores all non-base64 characters.
+ * This is how chunked (e.g. 76 character) data is handled, since CR and LF are silently ignored, but has
+ * implications for other bytes, too. This method subscribes to the garbage-in, garbage-out philosophy: it will not
+ * check the provided data for validity.
Thanks to "commons" project in ws.apache.org for the bitwise
+ * operations, and general approach. http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
+ *
+ * @param in byte[] array of ascii data to base64 decode.
+ * @param inPos Position to start reading data from.
+ * @param inAvail Amount of bytes available from input for encoding.
+ */
+ void decode(byte[] in, int inPos, int inAvail) {
+ if (eof) {
+ return;
+ }
+ if (inAvail < 0) {
+ eof = true;
+ }
+ for (int i = 0; i < inAvail; i++) {
+ ensureBufferSize(decodeSize);
+ byte b = in[inPos++];
+ if (b == PAD) {
+ // We're done.
+ eof = true;
+ break;
+ } else {
+ if (b >= 0 && b < DECODE_TABLE.length) {
+ int result = DECODE_TABLE[b];
+ if (result >= 0) {
+ modulus = (modulus + 1) % BYTES_PER_ENCODED_BLOCK;
+ bitWorkArea = (bitWorkArea << BITS_PER_ENCODED_BYTE) + result;
+ if (modulus == 0) {
+ buffer[pos++] = (byte)((bitWorkArea >> 16) & MASK_8BITS);
+ buffer[pos++] = (byte)((bitWorkArea >> 8) & MASK_8BITS);
+ buffer[pos++] = (byte)(bitWorkArea & MASK_8BITS);
+ }
+ }
+ }
+ }
+ }
- // Create this so can use the super-class method
- // Also ensures that the same roundings are performed by the ctor and the code
- Base64 b64 = isChunked ? new Base64(MIME_CHUNK_SIZE, CHUNK_SEPARATOR, urlSafe) : new Base64(0, CHUNK_SEPARATOR, urlSafe);
- long len = b64.getEncodedLength(binaryData);
- if (len > maxResultSize) {
- throw new IllegalArgumentException("Input array too big, the output array would be bigger (" +
- len +
- ") than the specified maximum size of " +
- maxResultSize);
- }
-
- return b64.encode(binaryData);
- }
+ // Two forms of EOF as far as base64 decoder is concerned: actual
+ // EOF (-1) and first time '=' character is encountered in stream.
+ // This approach makes the '=' padding characters completely optional.
+ if (eof && modulus != 0) {
+ ensureBufferSize(decodeSize);
+ // We have some spare bits remaining
+ // Output all whole multiples of 8 bits and ignore the rest
+ switch (modulus) {
+ // case 1: // 6 bits - ignore entirely
+ // break;
+ case 2:
+ bitWorkArea = bitWorkArea >> 4;
+ buffer[pos++] = (byte)((bitWorkArea) & MASK_8BITS);
+ break;
+ case 3:
+ bitWorkArea = bitWorkArea >> 2;
+ buffer[pos++] = (byte)((bitWorkArea >> 8) & MASK_8BITS);
+ buffer[pos++] = (byte)((bitWorkArea) & MASK_8BITS);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ /**
+ * Encodes binary data using the base64 algorithm but does not chunk the output.
+ *
+ * @param binaryData binary data to encode
+ * @return byte[] containing Base64 characters in their UTF-8 representation.
+ */
+ public static byte[] encodeBase64(byte[] binaryData) {
+ return encodeBase64(binaryData, false, false, Integer.MAX_VALUE);
+ }
- /**
- * Decodes Base64 data into octets
- *
- * @param base64Data
- * Byte array containing Base64 data
- * @return Array containing decoded data.
- */
- public static byte[] decodeBase64(byte[] base64Data) {
- return new Base64().decode(base64Data);
- }
+ /**
+ * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks.
+ *
+ * @param binaryData Array containing binary data to encode.
+ * @param isChunked if true this encoder will chunk the base64 output into 76 character blocks
+ * @param urlSafe if true this encoder will emit - and _ instead of the usual + and /
+ * characters.
+ * @param maxResultSize The maximum result size to accept.
+ * @return Base64-encoded data.
+ * @throws IllegalArgumentException Thrown when the input array needs an output array bigger than maxResultSize
+ * @since 1.4
+ */
+ public static byte[] encodeBase64(byte[] binaryData, boolean isChunked, boolean urlSafe, int maxResultSize) {
+ if (binaryData == null || binaryData.length == 0) {
+ return binaryData;
+ }
+ // Create this so can use the super-class method
+ // Also ensures that the same roundings are performed by the ctor and the code
+ Base64 b64 = isChunked ? new Base64(MIME_CHUNK_SIZE, CHUNK_SEPARATOR, urlSafe) : new Base64(0, CHUNK_SEPARATOR,
+ urlSafe);
+ long len = b64.getEncodedLength(binaryData);
+ if (len > maxResultSize) {
+ throw new IllegalArgumentException("Input array too big, the output array would be bigger (" +
+ len +
+ ") than the specified maximum size of " +
+ maxResultSize);
+ }
- /**
- * Returns whether or not the octet is in the Base32 alphabet.
- *
- * @param octet
- * The value to test
- * @return true if the value is defined in the the Base32 alphabet false otherwise.
- */
- protected boolean isInAlphabet(byte octet) {
- return octet >= 0 && octet < decodeTable.length && decodeTable[octet] != -1;
- }
+ return b64.encode(binaryData);
+ }
- /**
- * Below from base class
- */
+ /**
+ * Decodes Base64 data into octets
+ *
+ * @param base64Data Byte array containing Base64 data
+ * @return Array containing decoded data.
+ */
+ public static byte[] decodeBase64(byte[] base64Data) {
+ return new Base64().decode(base64Data);
+ }
- /**
- * MIME chunk size per RFC 2045 section 6.8.
- *
- *
- * The {@value} character limit does not count the trailing CRLF, but counts all other characters, including any
- * equal signs.
- *
- *
- * @see RFC 2045 section 6.8
- */
- private static final int MIME_CHUNK_SIZE = 76;
+ /**
+ * Returns whether or not the octet is in the Base32 alphabet.
+ *
+ * @param octet The value to test
+ * @return true if the value is defined in the the Base32 alphabet false otherwise.
+ */
+ protected boolean isInAlphabet(byte octet) {
+ return octet >= 0 && octet < decodeTable.length && decodeTable[octet] != -1;
+ }
- private static final int DEFAULT_BUFFER_RESIZE_FACTOR = 2;
+ /**
+ * Below from base class
+ */
- /**
- * Defines the default buffer size - currently {@value}
- * - must be large enough for at least one encoded block+separator
- */
- private static final int DEFAULT_BUFFER_SIZE = 8192;
+ /**
+ * MIME chunk size per RFC 2045 section 6.8.
+ *
+ *
The {@value} character limit does not count the trailing CRLF, but counts all other characters, including any
+ * equal signs.
+ *
+ * @see RFC 2045 section 6.8
+ */
+ private static final int MIME_CHUNK_SIZE = 76;
- /** Mask used to extract 8 bits, used in decoding bytes */
- private static final int MASK_8BITS = 0xff;
+ private static final int DEFAULT_BUFFER_RESIZE_FACTOR = 2;
- /**
- * Byte used to pad output.
- */
- private static final byte PAD_DEFAULT = '=';
+ /**
+ * Defines the default buffer size - currently {@value} - must be large enough for at least one encoded
+ * block+separator
+ */
+ private static final int DEFAULT_BUFFER_SIZE = 8192;
- private static final byte PAD = PAD_DEFAULT;
+ /**
+ * Mask used to extract 8 bits, used in decoding bytes
+ */
+ private static final int MASK_8BITS = 0xff;
- /** Number of bytes in each full block of unencoded data, e.g. 4 for Base64 and 5 for Base32 */
- private final int unencodedBlockSize;
+ /**
+ * Byte used to pad output.
+ */
+ private static final byte PAD_DEFAULT = '=';
- /** Number of bytes in each full block of encoded data, e.g. 3 for Base64 and 8 for Base32 */
- private final int encodedBlockSize;
+ private static final byte PAD = PAD_DEFAULT;
- /**
- * Chunksize for encoding. Not used when decoding.
- * A value of zero or less implies no chunking of the encoded data.
- * Rounded down to nearest multiple of encodedBlockSize.
- */
- private final int lineLength;
+ /**
+ * Number of bytes in each full block of unencoded data, e.g. 4 for Base64 and 5 for Base32
+ */
+ private final int unencodedBlockSize;
- /**
- * Size of chunk separator. Not used unless {@link #lineLength} > 0.
- */
- private final int chunkSeparatorLength;
+ /**
+ * Number of bytes in each full block of encoded data, e.g. 3 for Base64 and 8 for Base32
+ */
+ private final int encodedBlockSize;
- /**
- * Buffer for streaming.
- */
- private byte[] buffer;
+ /**
+ * Chunksize for encoding. Not used when decoding. A value of zero or less implies no chunking of the encoded data.
+ * Rounded down to nearest multiple of encodedBlockSize.
+ */
+ private final int lineLength;
- /**
- * Position where next character should be written in the buffer.
- */
- private int pos;
+ /**
+ * Size of chunk separator. Not used unless {@link #lineLength} > 0.
+ */
+ private final int chunkSeparatorLength;
- /**
- * Position where next character should be read from the buffer.
- */
- private int readPos;
+ /**
+ * Buffer for streaming.
+ */
+ private byte[] buffer;
- /**
- * Boolean flag to indicate the EOF has been reached. Once EOF has been reached, this object becomes useless,
- * and must be thrown away.
- */
- private boolean eof;
+ /**
+ * Position where next character should be written in the buffer.
+ */
+ private int pos;
- /**
- * Variable tracks how many characters have been written to the current line. Only used when encoding. We use it to
- * make sure each encoded line never goes beyond lineLength (if lineLength > 0).
- */
- private int currentLinePos;
+ /**
+ * Position where next character should be read from the buffer.
+ */
+ private int readPos;
- /**
- * Writes to the buffer only occur after every 3/5 reads when encoding, and every 4/8 reads when decoding.
- * This variable helps track that.
- */
- private int modulus;
+ /**
+ * Boolean flag to indicate the EOF has been reached. Once EOF has been reached, this object becomes useless, and
+ * must be thrown away.
+ */
+ private boolean eof;
- /**
- * Ensure that the buffer has room for size bytes
- *
- * @param size minimum spare space required
- */
- private void ensureBufferSize(int size){
- if ((buffer == null) || (buffer.length < pos + size)){
- if (buffer == null) {
- buffer = new byte[DEFAULT_BUFFER_SIZE];
- pos = 0;
- readPos = 0;
- } else {
- byte[] b = new byte[buffer.length * DEFAULT_BUFFER_RESIZE_FACTOR];
- System.arraycopy(buffer, 0, b, 0, buffer.length);
- buffer = b;
- }
- }
- }
+ /**
+ * Variable tracks how many characters have been written to the current line. Only used when encoding. We use it to
+ * make sure each encoded line never goes beyond lineLength (if lineLength > 0).
+ */
+ private int currentLinePos;
- /**
- * Extracts buffered data into the provided byte[] array, starting at position bPos,
- * up to a maximum of bAvail bytes. Returns how many bytes were actually extracted.
- *
- * @param b
- * byte[] array to extract the buffered data into.
- * @param bPos
- * position in byte[] array to start extraction at.
- * @param bAvail
- * amount of bytes we're allowed to extract. We may extract fewer (if fewer are available).
- * @return The number of bytes successfully extracted into the provided byte[] array.
- */
- private int readResults(byte[] b, int bPos, int bAvail) {
- if (buffer != null) {
- int len = Math.min(pos - readPos, bAvail);
- System.arraycopy(buffer, readPos, b, bPos, len);
- readPos += len;
- if (readPos >= pos) {
- buffer = null;
- }
- return len;
- }
- return eof ? -1 : 0;
- }
+ /**
+ * Writes to the buffer only occur after every 3/5 reads when encoding, and every 4/8 reads when decoding. This
+ * variable helps track that.
+ */
+ private int modulus;
- /**
- * Resets this object to its initial newly constructed state.
- */
- private void reset() {
- buffer = null;
- pos = 0;
- readPos = 0;
- currentLinePos = 0;
- modulus = 0;
- eof = false;
- }
+ /**
+ * Ensure that the buffer has room for size bytes
+ *
+ * @param size minimum spare space required
+ */
+ private void ensureBufferSize(int size) {
+ if ((buffer == null) || (buffer.length < pos + size)) {
+ if (buffer == null) {
+ buffer = new byte[DEFAULT_BUFFER_SIZE];
+ pos = 0;
+ readPos = 0;
+ } else {
+ byte[] b = new byte[buffer.length * DEFAULT_BUFFER_RESIZE_FACTOR];
+ System.arraycopy(buffer, 0, b, 0, buffer.length);
+ buffer = b;
+ }
+ }
+ }
- /**
- * Decodes a byte[] containing characters in the Base-N alphabet.
- *
- * @param pArray
- * A byte array containing Base-N character data
- * @return a byte array containing binary data
- */
- private byte[] decode(byte[] pArray) {
- reset();
- if (pArray == null || pArray.length == 0) {
- return pArray;
- }
- decode(pArray, 0, pArray.length);
- decode(pArray, 0, -1);
- byte[] result = new byte[pos];
- readResults(result, 0, result.length);
- return result;
- }
+ /**
+ * Extracts buffered data into the provided byte[] array, starting at position bPos, up to a maximum of bAvail
+ * bytes. Returns how many bytes were actually extracted.
+ *
+ * @param b byte[] array to extract the buffered data into.
+ * @param bPos position in byte[] array to start extraction at.
+ * @param bAvail amount of bytes we're allowed to extract. We may extract fewer (if fewer are available).
+ * @return The number of bytes successfully extracted into the provided byte[] array.
+ */
+ private int readResults(byte[] b, int bPos, int bAvail) {
+ if (buffer != null) {
+ int len = Math.min(pos - readPos, bAvail);
+ System.arraycopy(buffer, readPos, b, bPos, len);
+ readPos += len;
+ if (readPos >= pos) {
+ buffer = null;
+ }
+ return len;
+ }
+ return eof ? -1 : 0;
+ }
- /**
- * Encodes a byte[] containing binary data, into a byte[] containing characters in the alphabet.
- *
- * @param pArray
- * a byte array containing binary data
- * @return A byte array containing only the basen alphabetic character data
- */
- private byte[] encode(byte[] pArray) {
- reset();
- if (pArray == null || pArray.length == 0) {
- return pArray;
- }
- encode(pArray, 0, pArray.length);
- encode(pArray, 0, -1);
- byte[] buf = new byte[pos - readPos];
- readResults(buf, 0, buf.length);
- return buf;
- }
+ /**
+ * Resets this object to its initial newly constructed state.
+ */
+ private void reset() {
+ buffer = null;
+ pos = 0;
+ readPos = 0;
+ currentLinePos = 0;
+ modulus = 0;
+ eof = false;
+ }
- /**
- * Tests a given byte array to see if it contains any characters within the alphabet or PAD.
- *
- * Intended for use in checking line-ending arrays
- *
- * @param arrayOctet
- * byte array to test
- * @return true if any byte is a valid character in the alphabet or PAD; false otherwise
- */
- private boolean containsAlphabetOrPad(byte[] arrayOctet) {
- if (arrayOctet == null) {
- return false;
- }
- for (int i = 0; i < arrayOctet.length; i++) {
- if (PAD == arrayOctet[i] || isInAlphabet(arrayOctet[i])) {
- return true;
- }
- }
- return false;
- }
+ /**
+ * Decodes a byte[] containing characters in the Base-N alphabet.
+ *
+ * @param pArray A byte array containing Base-N character data
+ * @return a byte array containing binary data
+ */
+ private byte[] decode(byte[] pArray) {
+ reset();
+ if (pArray == null || pArray.length == 0) {
+ return pArray;
+ }
+ decode(pArray, 0, pArray.length);
+ decode(pArray, 0, -1);
+ byte[] result = new byte[pos];
+ readResults(result, 0, result.length);
+ return result;
+ }
- /**
- * Calculates the amount of space needed to encode the supplied array.
- *
- * @param pArray byte[] array which will later be encoded
- *
- * @return amount of space needed to encoded the supplied array.
- * Returns a long since a max-len array will require > Integer.MAX_VALUE
- */
- private long getEncodedLength(byte[] pArray) {
- // Calculate non-chunked size - rounded up to allow for padding
- // cast to long is needed to avoid possibility of overflow
- long len = ((pArray.length + unencodedBlockSize-1) / unencodedBlockSize) * (long) encodedBlockSize;
- if (lineLength > 0) {
- /**
- * Round up to nearest multiple
- */
- len += ((len + lineLength-1) / lineLength) * chunkSeparatorLength;
- }
- return len;
- }
+ /**
+ * Encodes a byte[] containing binary data, into a byte[] containing characters in the alphabet.
+ *
+ * @param pArray a byte array containing binary data
+ * @return A byte array containing only the basen alphabetic character data
+ */
+ private byte[] encode(byte[] pArray) {
+ reset();
+ if (pArray == null || pArray.length == 0) {
+ return pArray;
+ }
+ encode(pArray, 0, pArray.length);
+ encode(pArray, 0, -1);
+ byte[] buf = new byte[pos - readPos];
+ readResults(buf, 0, buf.length);
+ return buf;
+ }
+
+ /**
+ * Tests a given byte array to see if it contains any characters within the alphabet or PAD.
+ *
+ * Intended for use in checking line-ending arrays
+ *
+ * @param arrayOctet byte array to test
+ * @return true if any byte is a valid character in the alphabet or PAD; false otherwise
+ */
+ private boolean containsAlphabetOrPad(byte[] arrayOctet) {
+ if (arrayOctet == null) {
+ return false;
+ }
+ for (int i = 0; i < arrayOctet.length; i++) {
+ if (PAD == arrayOctet[i] || isInAlphabet(arrayOctet[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Calculates the amount of space needed to encode the supplied array.
+ *
+ * @param pArray byte[] array which will later be encoded
+ * @return amount of space needed to encoded the supplied array. Returns a long since a max-len array will require >
+ * Integer.MAX_VALUE
+ */
+ private long getEncodedLength(byte[] pArray) {
+ // Calculate non-chunked size - rounded up to allow for padding
+ // cast to long is needed to avoid possibility of overflow
+ long len = ((pArray.length + unencodedBlockSize - 1) / unencodedBlockSize) * (long)encodedBlockSize;
+ if (lineLength > 0) {
+ /**
+ * Round up to nearest multiple
+ */
+ len += ((len + lineLength - 1) / lineLength) * chunkSeparatorLength;
+ }
+ return len;
+ }
}
diff --git a/client/src/main/java/com/alibaba/nacos/client/identify/Constants.java b/client/src/main/java/com/alibaba/nacos/client/identify/Constants.java
index 2f566f754..339103f0c 100644
--- a/client/src/main/java/com/alibaba/nacos/client/identify/Constants.java
+++ b/client/src/main/java/com/alibaba/nacos/client/identify/Constants.java
@@ -17,16 +17,15 @@ package com.alibaba.nacos.client.identify;
/**
* Identify Constants
- *
- * @author Nacos
*
+ * @author Nacos
*/
public class Constants {
- public static final String ACCESS_KEY = "accessKey";
-
- public static final String SECRET_KEY = "secretKey";
-
- public static final String PROPERTIES_FILENAME = "spas.properties";
+ public static final String ACCESS_KEY = "accessKey";
+
+ public static final String SECRET_KEY = "secretKey";
+
+ public static final String PROPERTIES_FILENAME = "spas.properties";
public static final String CREDENTIAL_PATH = "/home/admin/.spas_key/";
diff --git a/client/src/main/java/com/alibaba/nacos/client/identify/CredentialListener.java b/client/src/main/java/com/alibaba/nacos/client/identify/CredentialListener.java
index 943facba9..a96c8ec60 100644
--- a/client/src/main/java/com/alibaba/nacos/client/identify/CredentialListener.java
+++ b/client/src/main/java/com/alibaba/nacos/client/identify/CredentialListener.java
@@ -17,13 +17,12 @@ package com.alibaba.nacos.client.identify;
/**
* Credential Listener
- *
- * @author Nacos
*
+ * @author Nacos
*/
public interface CredentialListener {
- /**
- * update Credential
- */
+ /**
+ * update Credential
+ */
public void onUpdateCredential();
}
diff --git a/client/src/main/java/com/alibaba/nacos/client/identify/CredentialService.java b/client/src/main/java/com/alibaba/nacos/client/identify/CredentialService.java
index cf8f792ca..063f18fbc 100644
--- a/client/src/main/java/com/alibaba/nacos/client/identify/CredentialService.java
+++ b/client/src/main/java/com/alibaba/nacos/client/identify/CredentialService.java
@@ -23,34 +23,33 @@ import java.util.concurrent.ConcurrentHashMap;
/**
* Credential Service
- *
- * @author Nacos
*
+ * @author Nacos
*/
public final class CredentialService implements SpasCredentialLoader {
- static final public Logger log = LogUtils.logger(CredentialService.class);
- private static ConcurrentHashMap instances = new ConcurrentHashMap();
+ static final public Logger log = LogUtils.logger(CredentialService.class);
+ private static ConcurrentHashMap instances
+ = new ConcurrentHashMap();
private String appName;
- private Credentials credentials = new Credentials();
+ private Credentials credentials = new Credentials();
private CredentialWatcher watcher;
private CredentialListener listener;
-
- private CredentialService(String appName) {
+
+ private CredentialService(String appName) {
if (appName == null) {
- String value = System.getProperty("project.name");
- if (StringUtils.isNotEmpty(value)) {
- appName = value;
- }
+ String value = System.getProperty("project.name");
+ if (StringUtils.isNotEmpty(value)) {
+ appName = value;
+ }
}
this.appName = appName;
watcher = new CredentialWatcher(appName, this);
- }
-
-
- public static CredentialService getInstance() {
+ }
+
+ public static CredentialService getInstance() {
return getInstance(null);
- }
+ }
public static CredentialService getInstance(String appName) {
String key = appName != null ? appName : Constants.NO_APP_NAME;
@@ -85,13 +84,13 @@ public final class CredentialService implements SpasCredentialLoader {
log.info(appName, this.getClass().getSimpleName() + " is freed");
}
- public Credentials getCredential() {
+ public Credentials getCredential() {
Credentials localCredential = credentials;
if (localCredential.valid()) {
return localCredential;
}
- return credentials;
- }
+ return credentials;
+ }
public void setCredential(Credentials credential) {
boolean changed = !(credentials == credential || (credentials != null && credentials.identical(credential)));
@@ -113,23 +112,23 @@ public final class CredentialService implements SpasCredentialLoader {
}
@Deprecated
- public void setAccessKey(String accessKey) {
- credentials.setAccessKey(accessKey);
- }
+ public void setAccessKey(String accessKey) {
+ credentials.setAccessKey(accessKey);
+ }
@Deprecated
- public void setSecretKey(String secretKey) {
- credentials.setSecretKey(secretKey);
- }
+ public void setSecretKey(String secretKey) {
+ credentials.setSecretKey(secretKey);
+ }
@Deprecated
- public String getAccessKey() {
- return credentials.getAccessKey();
- }
+ public String getAccessKey() {
+ return credentials.getAccessKey();
+ }
@Deprecated
- public String getSecretKey() {
- return credentials.getSecretKey();
- }
+ public String getSecretKey() {
+ return credentials.getSecretKey();
+ }
}
diff --git a/client/src/main/java/com/alibaba/nacos/client/identify/CredentialWatcher.java b/client/src/main/java/com/alibaba/nacos/client/identify/CredentialWatcher.java
index 553849ba9..4da1f9886 100644
--- a/client/src/main/java/com/alibaba/nacos/client/identify/CredentialWatcher.java
+++ b/client/src/main/java/com/alibaba/nacos/client/identify/CredentialWatcher.java
@@ -31,12 +31,11 @@ import com.alibaba.nacos.client.utils.StringUtils;
/**
* Credential Watcher
- *
- * @author Nacos
*
+ * @author Nacos
*/
public class CredentialWatcher {
- static final public Logger SpasLogger = LogUtils.logger(CredentialWatcher.class);
+ static final public Logger SpasLogger = LogUtils.logger(CredentialWatcher.class);
private static final long REFRESH_INTERVAL = 10 * 1000;
private CredentialService serviceInstance;
@@ -104,21 +103,20 @@ public class CredentialWatcher {
propertyPath = url.getPath();
}
if (propertyPath == null || propertyPath.isEmpty()) {
-
- String value = System.getProperty("spas.identity");
- if (StringUtils.isNotEmpty(value)) {
- propertyPath = value;
- }
- if (propertyPath == null || propertyPath.isEmpty()) {
- propertyPath = Constants.CREDENTIAL_PATH + (appName == null ? Constants.CREDENTIAL_DEFAULT : appName);
+
+ String value = System.getProperty("spas.identity");
+ if (StringUtils.isNotEmpty(value)) {
+ propertyPath = value;
}
- else {
+ if (propertyPath == null || propertyPath.isEmpty()) {
+ propertyPath = Constants.CREDENTIAL_PATH + (appName == null ? Constants.CREDENTIAL_DEFAULT
+ : appName);
+ } else {
if (logWarn) {
SpasLogger.info(appName, "Defined credential file: -D" + "spas.identity" + "=" + propertyPath);
}
}
- }
- else {
+ } else {
if (logWarn) {
SpasLogger.info(appName, "Load credential file from classpath: " + Constants.PROPERTIES_FILENAME);
}
@@ -130,7 +128,8 @@ public class CredentialWatcher {
try {
propertiesIS = new FileInputStream(propertyPath);
} catch (FileNotFoundException e) {
- if (appName != null && !appName.equals(Constants.CREDENTIAL_DEFAULT) && propertyPath.equals(Constants.CREDENTIAL_PATH + appName)) {
+ if (appName != null && !appName.equals(Constants.CREDENTIAL_DEFAULT) && propertyPath.equals(
+ Constants.CREDENTIAL_PATH + appName)) {
propertyPath = Constants.CREDENTIAL_PATH + Constants.CREDENTIAL_DEFAULT;
continue;
}
@@ -154,22 +153,21 @@ public class CredentialWatcher {
}
return;
}
- }
- else {
+ } else {
Properties properties = new Properties();
try {
properties.load(propertiesIS);
} catch (IOException e) {
- SpasLogger.error("26", "Unable to load credential file, appName:" + appName
- + "Unable to load credential file " + propertyPath, e);
- propertyPath = null;
+ SpasLogger.error("26", "Unable to load credential file, appName:" + appName
+ + "Unable to load credential file " + propertyPath, e);
+ propertyPath = null;
return;
} finally {
try {
propertiesIS.close();
} catch (IOException e) {
- SpasLogger.error("27", "Unable to close credential file, appName:" + appName
- + "Unable to close credential file " + propertyPath, e);
+ SpasLogger.error("27", "Unable to close credential file, appName:" + appName
+ + "Unable to close credential file " + propertyPath, e);
}
}
@@ -202,12 +200,12 @@ public class CredentialWatcher {
}
Credentials credential = new Credentials(accessKey, secretKey);
- if (!credential.valid()) {
- SpasLogger.warn("1", "Credential file missing required property" + appName + "Credential file missing "
- + Constants.ACCESS_KEY + " or " + Constants.SECRET_KEY);
- propertyPath = null;
- // return;
- }
+ if (!credential.valid()) {
+ SpasLogger.warn("1", "Credential file missing required property" + appName + "Credential file missing "
+ + Constants.ACCESS_KEY + " or " + Constants.SECRET_KEY);
+ propertyPath = null;
+ // return;
+ }
serviceInstance.setCredential(credential);
}
diff --git a/client/src/main/java/com/alibaba/nacos/client/identify/Credentials.java b/client/src/main/java/com/alibaba/nacos/client/identify/Credentials.java
index f54100bf6..a271561da 100644
--- a/client/src/main/java/com/alibaba/nacos/client/identify/Credentials.java
+++ b/client/src/main/java/com/alibaba/nacos/client/identify/Credentials.java
@@ -17,40 +17,39 @@ package com.alibaba.nacos.client.identify;
/**
* Credentials
- *
- * @author Nacos
*
+ * @author Nacos
*/
public class Credentials implements SpasCredential {
-
- private volatile String accessKey;
-
- private volatile String secretKey;
-
- public Credentials(String accessKey, String secretKey) {
- this.accessKey = accessKey;
- this.secretKey = secretKey;
- }
-
- public Credentials() {
- this(null, null);
- }
-
- public String getAccessKey() {
- return accessKey;
- }
- public void setAccessKey(String accessKey) {
- this.accessKey = accessKey;
- }
+ private volatile String accessKey;
- public String getSecretKey() {
- return secretKey;
- }
+ private volatile String secretKey;
- public void setSecretKey(String secretKey) {
- this.secretKey = secretKey;
- }
+ public Credentials(String accessKey, String secretKey) {
+ this.accessKey = accessKey;
+ this.secretKey = secretKey;
+ }
+
+ public Credentials() {
+ this(null, null);
+ }
+
+ public String getAccessKey() {
+ return accessKey;
+ }
+
+ public void setAccessKey(String accessKey) {
+ this.accessKey = accessKey;
+ }
+
+ public String getSecretKey() {
+ return secretKey;
+ }
+
+ public void setSecretKey(String secretKey) {
+ this.secretKey = secretKey;
+ }
public boolean valid() {
return accessKey != null && !accessKey.isEmpty() && secretKey != null && !secretKey.isEmpty();
@@ -58,8 +57,10 @@ public class Credentials implements SpasCredential {
public boolean identical(Credentials other) {
return this == other ||
- (other != null &&
- (accessKey == null && other.accessKey == null || accessKey != null && accessKey.equals(other.accessKey)) &&
- (secretKey == null && other.secretKey == null || secretKey != null && secretKey.equals(other.secretKey)));
+ (other != null &&
+ (accessKey == null && other.accessKey == null || accessKey != null && accessKey.equals(other.accessKey))
+ &&
+ (secretKey == null && other.secretKey == null || secretKey != null && secretKey.equals(
+ other.secretKey)));
}
}
diff --git a/client/src/main/java/com/alibaba/nacos/client/identify/STSConfig.java b/client/src/main/java/com/alibaba/nacos/client/identify/STSConfig.java
index e555c5353..139877468 100644
--- a/client/src/main/java/com/alibaba/nacos/client/identify/STSConfig.java
+++ b/client/src/main/java/com/alibaba/nacos/client/identify/STSConfig.java
@@ -19,110 +19,110 @@ import com.alibaba.nacos.client.utils.StringUtils;
/**
* Sts config
- *
+ *
* @author Nacos
*/
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
public class STSConfig {
- private static final String RAM_SECURITY_CREDENTIALS_URL
- = "";
- private String ramRoleName;
- /**
- * STS 临时凭证有效期剩余多少时开始刷新(允许本地时间比 STS 服务时间最多慢多久)
- */
- private int timeToRefreshInMillisecond = 3 * 60 * 1000;
- /**
- * 获取 STS 临时凭证的元数据接口(包含角色名称)
- */
- private String securityCredentialsUrl;
- /**
- * 设定 STS 临时凭证,不再通过元数据接口获取
- */
- private String securityCredentials;
- /**
- * 是否缓存
- */
- private boolean cacheSecurityCredentials = true;
+ private static final String RAM_SECURITY_CREDENTIALS_URL
+ = "";
+ private String ramRoleName;
+ /**
+ * STS 临时凭证有效期剩余多少时开始刷新(允许本地时间比 STS 服务时间最多慢多久)
+ */
+ private int timeToRefreshInMillisecond = 3 * 60 * 1000;
+ /**
+ * 获取 STS 临时凭证的元数据接口(包含角色名称)
+ */
+ private String securityCredentialsUrl;
+ /**
+ * 设定 STS 临时凭证,不再通过元数据接口获取
+ */
+ private String securityCredentials;
+ /**
+ * 是否缓存
+ */
+ private boolean cacheSecurityCredentials = true;
- private static class Singleton {
- private static final STSConfig INSTANCE = new STSConfig();
- }
+ private static class Singleton {
+ private static final STSConfig INSTANCE = new STSConfig();
+ }
- private STSConfig() {
- String ramRoleName = System.getProperty("ram.role.name");
- if (!StringUtils.isBlank(ramRoleName)) {
- setRamRoleName(ramRoleName);
- }
+ private STSConfig() {
+ String ramRoleName = System.getProperty("ram.role.name");
+ if (!StringUtils.isBlank(ramRoleName)) {
+ setRamRoleName(ramRoleName);
+ }
- String timeToRefreshInMillisecond = System.getProperty("time.to.refresh.in.millisecond");
- if (!StringUtils.isBlank(timeToRefreshInMillisecond)) {
- setTimeToRefreshInMillisecond(Integer.parseInt(timeToRefreshInMillisecond));
- }
+ String timeToRefreshInMillisecond = System.getProperty("time.to.refresh.in.millisecond");
+ if (!StringUtils.isBlank(timeToRefreshInMillisecond)) {
+ setTimeToRefreshInMillisecond(Integer.parseInt(timeToRefreshInMillisecond));
+ }
- String securityCredentials = System.getProperty("security.credentials");
- if (!StringUtils.isBlank(securityCredentials)) {
- setSecurityCredentials(securityCredentials);
- }
+ String securityCredentials = System.getProperty("security.credentials");
+ if (!StringUtils.isBlank(securityCredentials)) {
+ setSecurityCredentials(securityCredentials);
+ }
- String securityCredentialsUrl = System.getProperty("security.credentials.url");
- if (!StringUtils.isBlank(securityCredentialsUrl)) {
- setSecurityCredentialsUrl(securityCredentialsUrl);
- }
+ String securityCredentialsUrl = System.getProperty("security.credentials.url");
+ if (!StringUtils.isBlank(securityCredentialsUrl)) {
+ setSecurityCredentialsUrl(securityCredentialsUrl);
+ }
- String cacheSecurityCredentials = System.getProperty("cache.security.credentials");
- if (!StringUtils.isBlank(cacheSecurityCredentials)) {
- setCacheSecurityCredentials(Boolean.valueOf(cacheSecurityCredentials));
- }
- }
+ String cacheSecurityCredentials = System.getProperty("cache.security.credentials");
+ if (!StringUtils.isBlank(cacheSecurityCredentials)) {
+ setCacheSecurityCredentials(Boolean.valueOf(cacheSecurityCredentials));
+ }
+ }
- public static STSConfig getInstance() {
- return Singleton.INSTANCE;
- }
+ public static STSConfig getInstance() {
+ return Singleton.INSTANCE;
+ }
- public String getRamRoleName() {
- return ramRoleName;
- }
+ public String getRamRoleName() {
+ return ramRoleName;
+ }
- public void setRamRoleName(String ramRoleName) {
- this.ramRoleName = ramRoleName;
- }
+ public void setRamRoleName(String ramRoleName) {
+ this.ramRoleName = ramRoleName;
+ }
- public int getTimeToRefreshInMillisecond() {
- return timeToRefreshInMillisecond;
- }
+ public int getTimeToRefreshInMillisecond() {
+ return timeToRefreshInMillisecond;
+ }
- public void setTimeToRefreshInMillisecond(int timeToRefreshInMillisecond) {
- this.timeToRefreshInMillisecond = timeToRefreshInMillisecond;
- }
+ public void setTimeToRefreshInMillisecond(int timeToRefreshInMillisecond) {
+ this.timeToRefreshInMillisecond = timeToRefreshInMillisecond;
+ }
- public String getSecurityCredentialsUrl() {
- if (securityCredentialsUrl == null && ramRoleName != null) {
- return RAM_SECURITY_CREDENTIALS_URL + ramRoleName;
- }
- return securityCredentialsUrl;
- }
+ public String getSecurityCredentialsUrl() {
+ if (securityCredentialsUrl == null && ramRoleName != null) {
+ return RAM_SECURITY_CREDENTIALS_URL + ramRoleName;
+ }
+ return securityCredentialsUrl;
+ }
- public void setSecurityCredentialsUrl(String securityCredentialsUrl) {
- this.securityCredentialsUrl = securityCredentialsUrl;
- }
+ public void setSecurityCredentialsUrl(String securityCredentialsUrl) {
+ this.securityCredentialsUrl = securityCredentialsUrl;
+ }
- public String getSecurityCredentials() {
- return securityCredentials;
- }
+ public String getSecurityCredentials() {
+ return securityCredentials;
+ }
- public void setSecurityCredentials(String securityCredentials) {
- this.securityCredentials = securityCredentials;
- }
+ public void setSecurityCredentials(String securityCredentials) {
+ this.securityCredentials = securityCredentials;
+ }
- public boolean isSTSOn() {
- return StringUtils.isNotEmpty(getSecurityCredentials()) || StringUtils.isNotEmpty(getSecurityCredentialsUrl());
- }
+ public boolean isSTSOn() {
+ return StringUtils.isNotEmpty(getSecurityCredentials()) || StringUtils.isNotEmpty(getSecurityCredentialsUrl());
+ }
- public boolean isCacheSecurityCredentials() {
- return cacheSecurityCredentials;
- }
+ public boolean isCacheSecurityCredentials() {
+ return cacheSecurityCredentials;
+ }
- public void setCacheSecurityCredentials(boolean cacheSecurityCredentials) {
- this.cacheSecurityCredentials = cacheSecurityCredentials;
- }
+ public void setCacheSecurityCredentials(boolean cacheSecurityCredentials) {
+ this.cacheSecurityCredentials = cacheSecurityCredentials;
+ }
}
diff --git a/client/src/main/java/com/alibaba/nacos/client/identify/SpasCredential.java b/client/src/main/java/com/alibaba/nacos/client/identify/SpasCredential.java
index 8d6a2bd91..7849eaeef 100644
--- a/client/src/main/java/com/alibaba/nacos/client/identify/SpasCredential.java
+++ b/client/src/main/java/com/alibaba/nacos/client/identify/SpasCredential.java
@@ -17,22 +17,21 @@ package com.alibaba.nacos.client.identify;
/**
* Spas Credential Interface
- *
- * @author Nacos
*
+ * @author Nacos
*/
public interface SpasCredential {
- /**
- * get AccessKey
- *
- * @return AccessKey
- */
- public String getAccessKey();
+ /**
+ * get AccessKey
+ *
+ * @return AccessKey
+ */
+ public String getAccessKey();
- /**
- * get SecretKey
- *
- * @return SecretKey
- */
- public String getSecretKey();
+ /**
+ * get SecretKey
+ *
+ * @return SecretKey
+ */
+ public String getSecretKey();
}
diff --git a/client/src/main/java/com/alibaba/nacos/client/identify/SpasCredentialLoader.java b/client/src/main/java/com/alibaba/nacos/client/identify/SpasCredentialLoader.java
index 12012ee2a..9cd1d37d3 100644
--- a/client/src/main/java/com/alibaba/nacos/client/identify/SpasCredentialLoader.java
+++ b/client/src/main/java/com/alibaba/nacos/client/identify/SpasCredentialLoader.java
@@ -17,15 +17,14 @@ package com.alibaba.nacos.client.identify;
/**
* Spas Credential Loader
- *
- * @author Nacos
*
+ * @author Nacos
*/
public interface SpasCredentialLoader {
- /**
- * get Credential
- *
- * @return Credential
- */
+ /**
+ * get Credential
+ *
+ * @return Credential
+ */
SpasCredential getCredential();
}
diff --git a/client/src/main/java/com/alibaba/nacos/client/logger/Level.java b/client/src/main/java/com/alibaba/nacos/client/logger/Level.java
index 38522f801..4f7031cf5 100644
--- a/client/src/main/java/com/alibaba/nacos/client/logger/Level.java
+++ b/client/src/main/java/com/alibaba/nacos/client/logger/Level.java
@@ -17,14 +17,18 @@ package com.alibaba.nacos.client.logger;
/**
* 阿里中间件日志级别
- *
+ *
* @author zhuyong 2014年3月20日 上午9:57:27
*/
public enum Level {
- /**
- * log level
- */
- DEBUG("DEBUG"), INFO("INFO"), WARN("WARN"), ERROR("ERROR"), OFF("OFF");
+ /**
+ * log level
+ */
+ DEBUG("DEBUG"),
+ INFO("INFO"),
+ WARN("WARN"),
+ ERROR("ERROR"),
+ OFF("OFF");
private String name;
diff --git a/client/src/main/java/com/alibaba/nacos/client/logger/Logger.java b/client/src/main/java/com/alibaba/nacos/client/logger/Logger.java
index f38c3e811..35e1995ef 100644
--- a/client/src/main/java/com/alibaba/nacos/client/logger/Logger.java
+++ b/client/src/main/java/com/alibaba/nacos/client/logger/Logger.java
@@ -20,7 +20,7 @@ import com.alibaba.nacos.client.logger.option.ActivateOption;
/**
*
* 阿里中间件LoggerFactory,获取具体日志实现
@@ -57,17 +56,12 @@ public class LoggerFactory {
LogLog.info("Init JM logger with Slf4jLoggerFactory success, " + LoggerFactory.class.getClassLoader());
} catch (Throwable e1) {
try {
- setLoggerFactory(new Log4jLoggerFactory());
- LogLog.info("Init JM logger with Log4jLoggerFactory, " + LoggerFactory.class.getClassLoader());
+ setLoggerFactory(new Log4j2LoggerFactory());
+ LogLog.info("Init JM logger with Log4j2LoggerFactory, " + LoggerFactory.class.getClassLoader());
} catch (Throwable e2) {
- try {
- setLoggerFactory(new Log4j2LoggerFactory());
- LogLog.info("Init JM logger with Log4j2LoggerFactory, " + LoggerFactory.class.getClassLoader());
- } catch (Throwable e3) {
- setLoggerFactory(new NopLoggerFactory());
- LogLog.warn("Init JM logger with NopLoggerFactory, pay attention. "
- + LoggerFactory.class.getClassLoader(), e2);
- }
+ setLoggerFactory(new NopLoggerFactory());
+ LogLog.warn("Init JM logger with NopLoggerFactory, pay attention. "
+ + LoggerFactory.class.getClassLoader(), e2);
}
}
diff --git a/client/src/main/java/com/alibaba/nacos/client/logger/json/JSONArray.java b/client/src/main/java/com/alibaba/nacos/client/logger/json/JSONArray.java
index d14f47e70..99763cc61 100644
--- a/client/src/main/java/com/alibaba/nacos/client/logger/json/JSONArray.java
+++ b/client/src/main/java/com/alibaba/nacos/client/logger/json/JSONArray.java
@@ -28,371 +28,367 @@ import java.util.Iterator;
/**
* A JSON array. JSONObject supports java.util.List interface.
- *
- * @author FangYidong
+ *
+ * @author FangYidong
*/
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
public class JSONArray extends ArrayList implements JSONAware, JSONStreamAware {
- private static final long serialVersionUID = 3957988303675231981L;
-
- /**
- * Constructs an empty JSONArray.
- */
- public JSONArray(){
- super();
- }
-
- /**
- * Constructs a JSONArray containing the elements of the specified
- * collection, in the order they are returned by the collection's iterator.
- *
- * @param c the collection whose elements are to be placed into this JSONArray
- */
- public JSONArray(Collection c){
- super(c);
- }
-
+ private static final long serialVersionUID = 3957988303675231981L;
+
/**
- * Encode a list into JSON text and write it to out.
- * If this list is also a JSONStreamAware or a JSONAware, JSONStreamAware and JSONAware specific behaviours will be ignored at this top level.
- *
- * @see com.alibaba.nacos.client.logger.json.JSONValue#writeJSONString(Object, Writer)
- *
+ * Constructs an empty JSONArray.
+ */
+ public JSONArray() {
+ super();
+ }
+
+ /**
+ * Constructs a JSONArray containing the elements of the specified collection, in the order they are returned by the
+ * collection's iterator.
+ *
+ * @param c the collection whose elements are to be placed into this JSONArray
+ */
+ public JSONArray(Collection c) {
+ super(c);
+ }
+
+ /**
+ * Encode a list into JSON text and write it to out. If this list is also a JSONStreamAware or a JSONAware,
+ * JSONStreamAware and JSONAware specific behaviours will be ignored at this top level.
+ *
* @param collection
* @param out
+ * @see com.alibaba.nacos.client.logger.json.JSONValue#writeJSONString(Object, Writer)
*/
- public static void writeJSONString(Collection collection, Writer out) throws IOException{
- if(collection == null){
- out.write("null");
- return;
- }
-
- boolean first = true;
- Iterator iter=collection.iterator();
-
+ public static void writeJSONString(Collection collection, Writer out) throws IOException {
+ if (collection == null) {
+ out.write("null");
+ return;
+ }
+
+ boolean first = true;
+ Iterator iter = collection.iterator();
+
out.write('[');
- while(iter.hasNext()){
- if(first) {
+ while (iter.hasNext()) {
+ if (first) {
first = false;
- }
- else {
+ } else {
out.write(',');
}
- Object value=iter.next();
- if(value == null){
- out.write("null");
- continue;
- }
-
- JSONValue.writeJSONString(value, out);
- }
- out.write(']');
- }
-
- public void writeJSONString(Writer out) throws IOException{
- writeJSONString(this, out);
- }
-
- /**
- * Convert a list to JSON text. The result is a JSON array.
- * If this list is also a JSONAware, JSONAware specific behaviours will be omitted at this top level.
- *
- * @see com.alibaba.nacos.client.logger.json.JSONValue#toJSONString(Object)
- *
- * @param collection
- * @return JSON text, or "null" if list is null.
- */
- public static String toJSONString(Collection collection){
- final StringWriter writer = new StringWriter();
-
- try {
- writeJSONString(collection, writer);
- return writer.toString();
- } catch(IOException e){
- // This should never happen for a StringWriter
- throw new RuntimeException(e);
- }
- }
+ Object value = iter.next();
+ if (value == null) {
+ out.write("null");
+ continue;
+ }
- public static void writeJSONString(byte[] array, Writer out) throws IOException{
- if(array == null){
- out.write("null");
- } else if(array.length == 0) {
- out.write("[]");
- } else {
- out.write("[");
- out.write(String.valueOf(array[0]));
-
- for(int i = 1; i < array.length; i++){
- out.write(",");
- out.write(String.valueOf(array[i]));
- }
-
- out.write("]");
- }
- }
-
- public static String toJSONString(byte[] array){
- final StringWriter writer = new StringWriter();
-
- try {
- writeJSONString(array, writer);
- return writer.toString();
- } catch(IOException e){
- // This should never happen for a StringWriter
- throw new RuntimeException(e);
- }
- }
-
- public static void writeJSONString(short[] array, Writer out) throws IOException{
- if(array == null){
- out.write("null");
- } else if(array.length == 0) {
- out.write("[]");
- } else {
- out.write("[");
- out.write(String.valueOf(array[0]));
-
- for(int i = 1; i < array.length; i++){
- out.write(",");
- out.write(String.valueOf(array[i]));
- }
-
- out.write("]");
- }
- }
-
- public static String toJSONString(short[] array){
- final StringWriter writer = new StringWriter();
-
- try {
- writeJSONString(array, writer);
- return writer.toString();
- } catch(IOException e){
- // This should never happen for a StringWriter
- throw new RuntimeException(e);
- }
- }
-
- public static void writeJSONString(int[] array, Writer out) throws IOException{
- if(array == null){
- out.write("null");
- } else if(array.length == 0) {
- out.write("[]");
- } else {
- out.write("[");
- out.write(String.valueOf(array[0]));
-
- for(int i = 1; i < array.length; i++){
- out.write(",");
- out.write(String.valueOf(array[i]));
- }
-
- out.write("]");
- }
- }
-
- public static String toJSONString(int[] array){
- final StringWriter writer = new StringWriter();
-
- try {
- writeJSONString(array, writer);
- return writer.toString();
- } catch(IOException e){
- // This should never happen for a StringWriter
- throw new RuntimeException(e);
- }
- }
-
- public static void writeJSONString(long[] array, Writer out) throws IOException{
- if(array == null){
- out.write("null");
- } else if(array.length == 0) {
- out.write("[]");
- } else {
- out.write("[");
- out.write(String.valueOf(array[0]));
-
- for(int i = 1; i < array.length; i++){
- out.write(",");
- out.write(String.valueOf(array[i]));
- }
-
- out.write("]");
- }
- }
-
- public static String toJSONString(long[] array){
- final StringWriter writer = new StringWriter();
-
- try {
- writeJSONString(array, writer);
- return writer.toString();
- } catch(IOException e){
- // This should never happen for a StringWriter
- throw new RuntimeException(e);
- }
- }
-
- public static void writeJSONString(float[] array, Writer out) throws IOException{
- if(array == null){
- out.write("null");
- } else if(array.length == 0) {
- out.write("[]");
- } else {
- out.write("[");
- out.write(String.valueOf(array[0]));
-
- for(int i = 1; i < array.length; i++){
- out.write(",");
- out.write(String.valueOf(array[i]));
- }
-
- out.write("]");
- }
- }
-
- public static String toJSONString(float[] array){
- final StringWriter writer = new StringWriter();
-
- try {
- writeJSONString(array, writer);
- return writer.toString();
- } catch(IOException e){
- // This should never happen for a StringWriter
- throw new RuntimeException(e);
- }
- }
-
- public static void writeJSONString(double[] array, Writer out) throws IOException{
- if(array == null){
- out.write("null");
- } else if(array.length == 0) {
- out.write("[]");
- } else {
- out.write("[");
- out.write(String.valueOf(array[0]));
-
- for(int i = 1; i < array.length; i++){
- out.write(",");
- out.write(String.valueOf(array[i]));
- }
-
- out.write("]");
- }
- }
-
- public static String toJSONString(double[] array){
- final StringWriter writer = new StringWriter();
-
- try {
- writeJSONString(array, writer);
- return writer.toString();
- } catch(IOException e){
- // This should never happen for a StringWriter
- throw new RuntimeException(e);
- }
- }
-
- public static void writeJSONString(boolean[] array, Writer out) throws IOException{
- if(array == null){
- out.write("null");
- } else if(array.length == 0) {
- out.write("[]");
- } else {
- out.write("[");
- out.write(String.valueOf(array[0]));
-
- for(int i = 1; i < array.length; i++){
- out.write(",");
- out.write(String.valueOf(array[i]));
- }
-
- out.write("]");
- }
- }
-
- public static String toJSONString(boolean[] array){
- final StringWriter writer = new StringWriter();
-
- try {
- writeJSONString(array, writer);
- return writer.toString();
- } catch(IOException e){
- // This should never happen for a StringWriter
- throw new RuntimeException(e);
- }
- }
-
- public static void writeJSONString(char[] array, Writer out) throws IOException{
- if(array == null){
- out.write("null");
- } else if(array.length == 0) {
- out.write("[]");
- } else {
- out.write("[\"");
- out.write(String.valueOf(array[0]));
-
- for(int i = 1; i < array.length; i++){
- out.write("\",\"");
- out.write(String.valueOf(array[i]));
- }
-
- out.write("\"]");
- }
- }
-
- public static String toJSONString(char[] array){
- final StringWriter writer = new StringWriter();
-
- try {
- writeJSONString(array, writer);
- return writer.toString();
- } catch(IOException e){
- // This should never happen for a StringWriter
- throw new RuntimeException(e);
- }
- }
-
- public static void writeJSONString(Object[] array, Writer out) throws IOException{
- if(array == null){
- out.write("null");
- } else if(array.length == 0) {
- out.write("[]");
- } else {
- out.write("[");
- JSONValue.writeJSONString(array[0], out);
-
- for(int i = 1; i < array.length; i++){
- out.write(",");
- JSONValue.writeJSONString(array[i], out);
- }
-
- out.write("]");
- }
- }
-
- public static String toJSONString(Object[] array){
- final StringWriter writer = new StringWriter();
-
- try {
- writeJSONString(array, writer);
- return writer.toString();
- } catch(IOException e){
- // This should never happen for a StringWriter
- throw new RuntimeException(e);
- }
- }
-
- public String toJSONString(){
- return toJSONString(this);
- }
+ JSONValue.writeJSONString(value, out);
+ }
+ out.write(']');
+ }
- /**
- * Returns a string representation of this array. This is equivalent to
- * calling {@link JSONArray#toJSONString()}.
- */
- public String toString() {
- return toJSONString();
- }
+ public void writeJSONString(Writer out) throws IOException {
+ writeJSONString(this, out);
+ }
+
+ /**
+ * Convert a list to JSON text. The result is a JSON array. If this list is also a JSONAware, JSONAware specific
+ * behaviours will be omitted at this top level.
+ *
+ * @param collection
+ * @return JSON text, or "null" if list is null.
+ * @see com.alibaba.nacos.client.logger.json.JSONValue#toJSONString(Object)
+ */
+ public static String toJSONString(Collection collection) {
+ final StringWriter writer = new StringWriter();
+
+ try {
+ writeJSONString(collection, writer);
+ return writer.toString();
+ } catch (IOException e) {
+ // This should never happen for a StringWriter
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void writeJSONString(byte[] array, Writer out) throws IOException {
+ if (array == null) {
+ out.write("null");
+ } else if (array.length == 0) {
+ out.write("[]");
+ } else {
+ out.write("[");
+ out.write(String.valueOf(array[0]));
+
+ for (int i = 1; i < array.length; i++) {
+ out.write(",");
+ out.write(String.valueOf(array[i]));
+ }
+
+ out.write("]");
+ }
+ }
+
+ public static String toJSONString(byte[] array) {
+ final StringWriter writer = new StringWriter();
+
+ try {
+ writeJSONString(array, writer);
+ return writer.toString();
+ } catch (IOException e) {
+ // This should never happen for a StringWriter
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void writeJSONString(short[] array, Writer out) throws IOException {
+ if (array == null) {
+ out.write("null");
+ } else if (array.length == 0) {
+ out.write("[]");
+ } else {
+ out.write("[");
+ out.write(String.valueOf(array[0]));
+
+ for (int i = 1; i < array.length; i++) {
+ out.write(",");
+ out.write(String.valueOf(array[i]));
+ }
+
+ out.write("]");
+ }
+ }
+
+ public static String toJSONString(short[] array) {
+ final StringWriter writer = new StringWriter();
+
+ try {
+ writeJSONString(array, writer);
+ return writer.toString();
+ } catch (IOException e) {
+ // This should never happen for a StringWriter
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void writeJSONString(int[] array, Writer out) throws IOException {
+ if (array == null) {
+ out.write("null");
+ } else if (array.length == 0) {
+ out.write("[]");
+ } else {
+ out.write("[");
+ out.write(String.valueOf(array[0]));
+
+ for (int i = 1; i < array.length; i++) {
+ out.write(",");
+ out.write(String.valueOf(array[i]));
+ }
+
+ out.write("]");
+ }
+ }
+
+ public static String toJSONString(int[] array) {
+ final StringWriter writer = new StringWriter();
+
+ try {
+ writeJSONString(array, writer);
+ return writer.toString();
+ } catch (IOException e) {
+ // This should never happen for a StringWriter
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void writeJSONString(long[] array, Writer out) throws IOException {
+ if (array == null) {
+ out.write("null");
+ } else if (array.length == 0) {
+ out.write("[]");
+ } else {
+ out.write("[");
+ out.write(String.valueOf(array[0]));
+
+ for (int i = 1; i < array.length; i++) {
+ out.write(",");
+ out.write(String.valueOf(array[i]));
+ }
+
+ out.write("]");
+ }
+ }
+
+ public static String toJSONString(long[] array) {
+ final StringWriter writer = new StringWriter();
+
+ try {
+ writeJSONString(array, writer);
+ return writer.toString();
+ } catch (IOException e) {
+ // This should never happen for a StringWriter
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void writeJSONString(float[] array, Writer out) throws IOException {
+ if (array == null) {
+ out.write("null");
+ } else if (array.length == 0) {
+ out.write("[]");
+ } else {
+ out.write("[");
+ out.write(String.valueOf(array[0]));
+
+ for (int i = 1; i < array.length; i++) {
+ out.write(",");
+ out.write(String.valueOf(array[i]));
+ }
+
+ out.write("]");
+ }
+ }
+
+ public static String toJSONString(float[] array) {
+ final StringWriter writer = new StringWriter();
+
+ try {
+ writeJSONString(array, writer);
+ return writer.toString();
+ } catch (IOException e) {
+ // This should never happen for a StringWriter
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void writeJSONString(double[] array, Writer out) throws IOException {
+ if (array == null) {
+ out.write("null");
+ } else if (array.length == 0) {
+ out.write("[]");
+ } else {
+ out.write("[");
+ out.write(String.valueOf(array[0]));
+
+ for (int i = 1; i < array.length; i++) {
+ out.write(",");
+ out.write(String.valueOf(array[i]));
+ }
+
+ out.write("]");
+ }
+ }
+
+ public static String toJSONString(double[] array) {
+ final StringWriter writer = new StringWriter();
+
+ try {
+ writeJSONString(array, writer);
+ return writer.toString();
+ } catch (IOException e) {
+ // This should never happen for a StringWriter
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void writeJSONString(boolean[] array, Writer out) throws IOException {
+ if (array == null) {
+ out.write("null");
+ } else if (array.length == 0) {
+ out.write("[]");
+ } else {
+ out.write("[");
+ out.write(String.valueOf(array[0]));
+
+ for (int i = 1; i < array.length; i++) {
+ out.write(",");
+ out.write(String.valueOf(array[i]));
+ }
+
+ out.write("]");
+ }
+ }
+
+ public static String toJSONString(boolean[] array) {
+ final StringWriter writer = new StringWriter();
+
+ try {
+ writeJSONString(array, writer);
+ return writer.toString();
+ } catch (IOException e) {
+ // This should never happen for a StringWriter
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void writeJSONString(char[] array, Writer out) throws IOException {
+ if (array == null) {
+ out.write("null");
+ } else if (array.length == 0) {
+ out.write("[]");
+ } else {
+ out.write("[\"");
+ out.write(String.valueOf(array[0]));
+
+ for (int i = 1; i < array.length; i++) {
+ out.write("\",\"");
+ out.write(String.valueOf(array[i]));
+ }
+
+ out.write("\"]");
+ }
+ }
+
+ public static String toJSONString(char[] array) {
+ final StringWriter writer = new StringWriter();
+
+ try {
+ writeJSONString(array, writer);
+ return writer.toString();
+ } catch (IOException e) {
+ // This should never happen for a StringWriter
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void writeJSONString(Object[] array, Writer out) throws IOException {
+ if (array == null) {
+ out.write("null");
+ } else if (array.length == 0) {
+ out.write("[]");
+ } else {
+ out.write("[");
+ JSONValue.writeJSONString(array[0], out);
+
+ for (int i = 1; i < array.length; i++) {
+ out.write(",");
+ JSONValue.writeJSONString(array[i], out);
+ }
+
+ out.write("]");
+ }
+ }
+
+ public static String toJSONString(Object[] array) {
+ final StringWriter writer = new StringWriter();
+
+ try {
+ writeJSONString(array, writer);
+ return writer.toString();
+ } catch (IOException e) {
+ // This should never happen for a StringWriter
+ throw new RuntimeException(e);
+ }
+ }
+
+ public String toJSONString() {
+ return toJSONString(this);
+ }
+
+ /**
+ * Returns a string representation of this array. This is equivalent to calling {@link JSONArray#toJSONString()}.
+ */
+ public String toString() {
+ return toJSONString();
+ }
}
diff --git a/client/src/main/java/com/alibaba/nacos/client/logger/json/JSONAware.java b/client/src/main/java/com/alibaba/nacos/client/logger/json/JSONAware.java
index 778cdb158..2b2ebc1f7 100644
--- a/client/src/main/java/com/alibaba/nacos/client/logger/json/JSONAware.java
+++ b/client/src/main/java/com/alibaba/nacos/client/logger/json/JSONAware.java
@@ -16,15 +16,16 @@
package com.alibaba.nacos.client.logger.json;
/**
- * Beans that support customized output of JSON text shall implement this interface.
- * @author FangYidong
+ * Beans that support customized output of JSON text shall implement this interface.
+ *
+ * @author FangYidong
*/
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
public interface JSONAware {
- /**
- * format change
- *
- * @return JSON text
- */
- String toJSONString();
+ /**
+ * format change
+ *
+ * @return JSON text
+ */
+ String toJSONString();
}
diff --git a/client/src/main/java/com/alibaba/nacos/client/logger/json/JSONObject.java b/client/src/main/java/com/alibaba/nacos/client/logger/json/JSONObject.java
index 836aa2b69..66439f038 100644
--- a/client/src/main/java/com/alibaba/nacos/client/logger/json/JSONObject.java
+++ b/client/src/main/java/com/alibaba/nacos/client/logger/json/JSONObject.java
@@ -28,125 +28,118 @@ import java.util.Map;
/**
* A JSON object. Key value pairs are unordered. JSONObject supports java.util.Map interface.
- *
- * @author FangYidong
+ *
+ * @author FangYidong
*/
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
-public class JSONObject extends HashMap implements Map, JSONAware, JSONStreamAware{
-
- private static final long serialVersionUID = -503443796854799292L;
-
-
- public JSONObject() {
- super();
- }
+public class JSONObject extends HashMap implements Map, JSONAware, JSONStreamAware {
- /**
- * Allows creation of a JSONObject from a Map. After that, both the
- * generated JSONObject and the Map can be modified independently.
- *
- * @param map
- */
- public JSONObject(Map map) {
- super(map);
- }
+ private static final long serialVersionUID = -503443796854799292L;
+ public JSONObject() {
+ super();
+ }
/**
- * Encode a map into JSON text and write it to out.
- * If this map is also a JSONAware or JSONStreamAware, JSONAware or JSONStreamAware specific behaviours will be ignored at this top level.
- *
- * @see com.alibaba.nacos.client.logger.json.JSONValue#writeJSONString(Object, Writer)
- *
+ * Allows creation of a JSONObject from a Map. After that, both the generated JSONObject and the Map can be modified
+ * independently.
+ *
+ * @param map
+ */
+ public JSONObject(Map map) {
+ super(map);
+ }
+
+ /**
+ * Encode a map into JSON text and write it to out. If this map is also a JSONAware or JSONStreamAware, JSONAware or
+ * JSONStreamAware specific behaviours will be ignored at this top level.
+ *
* @param map
* @param out
+ * @see com.alibaba.nacos.client.logger.json.JSONValue#writeJSONString(Object, Writer)
*/
- public static void writeJSONString(Map map, Writer out) throws IOException {
- if(map == null){
- out.write("null");
- return;
- }
-
- boolean first = true;
- Iterator iter=map.entrySet().iterator();
-
+ public static void writeJSONString(Map map, Writer out) throws IOException {
+ if (map == null) {
+ out.write("null");
+ return;
+ }
+
+ boolean first = true;
+ Iterator iter = map.entrySet().iterator();
+
out.write('{');
- while(iter.hasNext()){
- if (first) {
- first = false;
- }
- else {
- out.write(',');
- }
- Map.Entry entry = (Map.Entry) iter.next();
+ while (iter.hasNext()) {
+ if (first) {
+ first = false;
+ } else {
+ out.write(',');
+ }
+ Map.Entry entry = (Map.Entry)iter.next();
out.write('\"');
out.write(escape(String.valueOf(entry.getKey())));
out.write('\"');
out.write(':');
- JSONValue.writeJSONString(entry.getValue(), out);
- }
- out.write('}');
- }
+ JSONValue.writeJSONString(entry.getValue(), out);
+ }
+ out.write('}');
+ }
- public void writeJSONString(Writer out) throws IOException{
- writeJSONString(this, out);
- }
-
- /**
- * Convert a map to JSON text. The result is a JSON object.
- * If this map is also a JSONAware, JSONAware specific behaviours will be omitted at this top level.
- *
- * @see com.alibaba.nacos.client.logger.json.JSONValue#toJSONString(Object)
- *
- * @param map
- * @return JSON text, or "null" if map is null.
- */
- public static String toJSONString(Map map){
- final StringWriter writer = new StringWriter();
-
- try {
- writeJSONString(map, writer);
- return writer.toString();
- } catch (IOException e) {
- // This should never happen with a StringWriter
- throw new RuntimeException(e);
- }
- }
-
- public String toJSONString(){
- return toJSONString(this);
- }
-
- public String toString(){
- return toJSONString();
- }
+ public void writeJSONString(Writer out) throws IOException {
+ writeJSONString(this, out);
+ }
- public static String toString(String key,Object value){
+ /**
+ * Convert a map to JSON text. The result is a JSON object. If this map is also a JSONAware, JSONAware specific
+ * behaviours will be omitted at this top level.
+ *
+ * @param map
+ * @return JSON text, or "null" if map is null.
+ * @see com.alibaba.nacos.client.logger.json.JSONValue#toJSONString(Object)
+ */
+ public static String toJSONString(Map map) {
+ final StringWriter writer = new StringWriter();
+
+ try {
+ writeJSONString(map, writer);
+ return writer.toString();
+ } catch (IOException e) {
+ // This should never happen with a StringWriter
+ throw new RuntimeException(e);
+ }
+ }
+
+ public String toJSONString() {
+ return toJSONString(this);
+ }
+
+ public String toString() {
+ return toJSONString();
+ }
+
+ public static String toString(String key, Object value) {
StringBuffer sb = new StringBuffer();
sb.append('\"');
- if(key == null) {
+ if (key == null) {
sb.append("null");
- }
- else {
+ } else {
JSONValue.escape(key, sb);
}
- sb.append('\"').append(':');
-
- sb.append(JSONValue.toJSONString(value));
-
- return sb.toString();
- }
-
- /**
- * Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters (U+0000 through U+001F).
- * It's the same as JSONValue.escape() only for compatibility here.
- *
- * @see com.alibaba.nacos.client.logger.json.JSONValue#escape(String)
- *
- * @param s
- * @return
- */
- public static String escape(String s){
- return JSONValue.escape(s);
- }
+ sb.append('\"').append(':');
+
+ sb.append(JSONValue.toJSONString(value));
+
+ return sb.toString();
+ }
+
+ /**
+ * Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters (U+0000 through U+001F). It's the same as
+ * JSONValue.escape() only for compatibility here.
+ *
+ * @param s
+ * @return
+ * @see com.alibaba.nacos.client.logger.json.JSONValue#escape(String)
+ */
+ public static String escape(String s) {
+ return JSONValue.escape(s);
+ }
}
diff --git a/client/src/main/java/com/alibaba/nacos/client/logger/json/JSONStreamAware.java b/client/src/main/java/com/alibaba/nacos/client/logger/json/JSONStreamAware.java
index 97c757902..5946913cb 100644
--- a/client/src/main/java/com/alibaba/nacos/client/logger/json/JSONStreamAware.java
+++ b/client/src/main/java/com/alibaba/nacos/client/logger/json/JSONStreamAware.java
@@ -19,20 +19,17 @@ import java.io.IOException;
import java.io.Writer;
/**
- * Beans that support customized output of JSON text to a writer shall implement
- * this interface.
- *
- * @author FangYidong
+ * Beans that support customized output of JSON text to a writer shall implement this interface.
+ *
+ * @author FangYidong
*/
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
public interface JSONStreamAware {
- /**
- * write JSON string to out.
- *
- * @param out
- * out writer
- * @throws IOException
- * Exception
- */
- void writeJSONString(Writer out) throws IOException;
+ /**
+ * write JSON string to out.
+ *
+ * @param out out writer
+ * @throws IOException Exception
+ */
+ void writeJSONString(Writer out) throws IOException;
}
diff --git a/client/src/main/java/com/alibaba/nacos/client/logger/json/JSONValue.java b/client/src/main/java/com/alibaba/nacos/client/logger/json/JSONValue.java
index 47e15586a..dfbac41e8 100644
--- a/client/src/main/java/com/alibaba/nacos/client/logger/json/JSONValue.java
+++ b/client/src/main/java/com/alibaba/nacos/client/logger/json/JSONValue.java
@@ -30,314 +30,286 @@ import java.util.Map;
import com.alibaba.nacos.client.logger.json.parser.JSONParser;
import com.alibaba.nacos.client.logger.json.parser.ParseException;
-
-
/**
- * @author FangYidong
+ * @author FangYidong
*/
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
public class JSONValue {
- /**
- * Parse JSON text into java object from the input source.
- * Please use parseWithException() if you don't want to ignore the exception.
- *
- * @see com.alibaba.nacos.client.logger.jsonparser.JSONParser#parse(Reader)
- * @see #parseWithException(Reader)
- *
- * @param in
- * @return Instance of the following:
- * com.alibaba.nacos.client.logger.jsonJSONObject,
- * com.alibaba.nacos.client.logger.jsonJSONArray,
- * java.lang.String,
- * java.lang.Number,
- * java.lang.Boolean,
- * null
- *
- * @deprecated this method may throw an {@code Error} instead of returning
- * {@code null}; please use {@link JSONValue#parseWithException(Reader)}
- * instead
- */
- public static Object parse(Reader in){
- try{
- JSONParser parser=new JSONParser();
- return parser.parse(in);
- }
- catch(Exception e){
- return null;
- }
- }
-
- /**
- * Parse JSON text into java object from the given string.
- * Please use parseWithException() if you don't want to ignore the exception.
- *
- * @see com.alibaba.nacos.client.logger.jsonparser.JSONParser#parse(Reader)
- * @see #parseWithException(Reader)
- *
- * @param s
- * @return Instance of the following:
- * com.alibaba.nacos.client.logger.jsonJSONObject,
- * com.alibaba.nacos.client.logger.jsonJSONArray,
- * java.lang.String,
- * java.lang.Number,
- * java.lang.Boolean,
- * null
- *
- * @deprecated this method may throw an {@code Error} instead of returning
- * {@code null}; please use {@link JSONValue#parseWithException(String)}
- * instead
- */
- public static Object parse(String s){
- StringReader in=new StringReader(s);
- return parse(in);
- }
-
- /**
- * Parse JSON text into java object from the input source.
- *
- * @see com.alibaba.nacos.client.logger.jsonparser.JSONParser
- *
- * @param in
- * @return Instance of the following:
- * com.alibaba.nacos.client.logger.jsonJSONObject,
- * com.alibaba.nacos.client.logger.jsonJSONArray,
- * java.lang.String,
- * java.lang.Number,
- * java.lang.Boolean,
- * null
- *
- * @throws IOException
- * @throws ParseException
- */
- public static Object parseWithException(Reader in) throws IOException, ParseException {
- JSONParser parser=new JSONParser();
- return parser.parse(in);
- }
-
- public static Object parseWithException(String s) throws ParseException{
- JSONParser parser=new JSONParser();
- return parser.parse(s);
- }
-
+ /**
+ * Parse JSON text into java object from the input source. Please use parseWithException() if you don't want to
+ * ignore the exception.
+ *
+ * @param in
+ * @return Instance of the following: com.alibaba.nacos.client.logger.jsonJSONObject,
+ * com.alibaba.nacos.client.logger.jsonJSONArray, java.lang.String, java.lang.Number, java.lang.Boolean, null
+ * @see com.alibaba.nacos.client.logger.jsonparser.JSONParser#parse(Reader)
+ * @see #parseWithException(Reader)
+ * @deprecated this method may throw an {@code Error} instead of returning {@code null}; please use {@link
+ * JSONValue#parseWithException(Reader)} instead
+ */
+ public static Object parse(Reader in) {
+ try {
+ JSONParser parser = new JSONParser();
+ return parser.parse(in);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Parse JSON text into java object from the given string. Please use parseWithException() if you don't want to
+ * ignore the exception.
+ *
+ * @param s
+ * @return Instance of the following: com.alibaba.nacos.client.logger.jsonJSONObject,
+ * com.alibaba.nacos.client.logger.jsonJSONArray, java.lang.String, java.lang.Number, java.lang.Boolean, null
+ * @see com.alibaba.nacos.client.logger.jsonparser.JSONParser#parse(Reader)
+ * @see #parseWithException(Reader)
+ * @deprecated this method may throw an {@code Error} instead of returning {@code null}; please use {@link
+ * JSONValue#parseWithException(String)} instead
+ */
+ public static Object parse(String s) {
+ StringReader in = new StringReader(s);
+ return parse(in);
+ }
+
+ /**
+ * Parse JSON text into java object from the input source.
+ *
+ * @param in
+ * @return Instance of the following: com.alibaba.nacos.client.logger.jsonJSONObject,
+ * com.alibaba.nacos.client.logger.jsonJSONArray, java.lang.String, java.lang.Number, java.lang.Boolean, null
+ * @throws IOException
+ * @throws ParseException
+ * @see com.alibaba.nacos.client.logger.jsonparser.JSONParser
+ */
+ public static Object parseWithException(Reader in) throws IOException, ParseException {
+ JSONParser parser = new JSONParser();
+ return parser.parse(in);
+ }
+
+ public static Object parseWithException(String s) throws ParseException {
+ JSONParser parser = new JSONParser();
+ return parser.parse(s);
+ }
+
/**
* Encode an object into JSON text and write it to out.
*
- * If this object is a Map or a List, and it's also a JSONStreamAware or a JSONAware, JSONStreamAware or JSONAware will be considered firstly.
+ * If this object is a Map or a List, and it's also a JSONStreamAware or a JSONAware, JSONStreamAware or JSONAware
+ * will be considered firstly.
*