fixed conflict
This commit is contained in:
commit
0a5f627808
16
.editorconfig
Normal file
16
.editorconfig
Normal file
@ -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
|
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -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.
|
||||
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -5,8 +5,11 @@
|
||||
target
|
||||
.project
|
||||
.idea
|
||||
.vscode
|
||||
.DS_Store
|
||||
.factorypath
|
||||
/logs
|
||||
*.iml
|
||||
node_modules
|
||||
test/derby.log
|
||||
derby.log
|
||||
|
@ -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
|
||||
|
105
CHANGELOG.md
105
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:
|
||||
|
73
CODE_OF_CONDUCT.md
Normal file
73
CODE_OF_CONDUCT.md
Normal file
@ -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
|
135
CONTRIBUTING.md
135
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."
|
||||
|
74
README.md
74
README.md
@ -1,12 +1,16 @@
|
||||
## Nacos
|
||||
|
||||
<img src="doc/Nacos_Logo.png" width="50%" height="50%" />
|
||||
|
||||
# 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)
|
||||
|
||||
-------
|
||||
<img src="doc/Nacos_Logo.png" width="50%" height="50%" />
|
||||
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)
|
||||
|
@ -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/
|
||||
[filing-good-bugs]:http://fantasai.inkedblade.net/style/talks/filing-good-bugs/
|
||||
|
67
api/pom.xml
67
api/pom.xml
@ -12,30 +12,55 @@
|
||||
limitations under the License.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-all</artifactId>
|
||||
<version>0.2.1</version>
|
||||
</parent>
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-all</artifactId>
|
||||
<version>0.7.0</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>nacos-api</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<artifactId>nacos-api</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>nacos-api ${project.version}</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
<name>nacos-api ${project.version}</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>7</source>
|
||||
<target>7</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
@ -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
|
||||
|
@ -38,4 +38,6 @@ public class PropertyKeyConst {
|
||||
|
||||
public final static String ENCODE = "encode";
|
||||
|
||||
public final static String NAMING_LOAD_CACHE_AT_START = "namingLoadCacheAtStart";
|
||||
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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 <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||
*/
|
||||
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<String, String> 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<String, String> getLabels() {
|
||||
return labels;
|
||||
}
|
||||
|
||||
public void setLabels(Map<String, String> labels) {
|
||||
this.labels = labels;
|
||||
}
|
||||
}
|
@ -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 <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
@ -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 <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||
*/
|
||||
public enum EntityEventType {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
ENTITY_ADD_OR_UPDATE,
|
||||
/**
|
||||
*
|
||||
*/
|
||||
ENTITY_REMOVE
|
||||
}
|
52
api/src/main/java/com/alibaba/nacos/api/cmdb/pojo/Label.java
Normal file
52
api/src/main/java/com/alibaba/nacos/api/cmdb/pojo/Label.java
Normal file
@ -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 <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||
*/
|
||||
public class Label {
|
||||
|
||||
private String name;
|
||||
private Set<String> values;
|
||||
private String description;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Set<String> getValues() {
|
||||
return values;
|
||||
}
|
||||
|
||||
public void setValues(Set<String> values) {
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
}
|
@ -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 <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||
*/
|
||||
public enum PreservedEntityTypes {
|
||||
/**
|
||||
* Ip
|
||||
*/
|
||||
ip,
|
||||
/**
|
||||
* Service
|
||||
*/
|
||||
service
|
||||
}
|
@ -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 <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||
*/
|
||||
public interface CmdbService {
|
||||
|
||||
/**
|
||||
* Get all label names stored in CMDB
|
||||
*
|
||||
* @return label name set
|
||||
*/
|
||||
Set<String> getLabelNames();
|
||||
|
||||
/**
|
||||
* Get all possible entity types in CMDB
|
||||
*
|
||||
* @return all entity types
|
||||
*/
|
||||
Set<String> 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<String, String> getLabelValues(String entityName, String entityType);
|
||||
|
||||
/**
|
||||
* Dump all entities in CMDB
|
||||
*
|
||||
* @return all entities
|
||||
*/
|
||||
Map<String, Map<String, Entity>> getAllEntities();
|
||||
|
||||
/**
|
||||
* get label change events
|
||||
*
|
||||
* @param timestamp start time of generated events
|
||||
* @return label events
|
||||
*/
|
||||
List<EntityEvent> getEntityEvents(long timestamp);
|
||||
|
||||
/**
|
||||
* Get single entity
|
||||
*
|
||||
* @param entityName name of entity
|
||||
* @param entityType type of entity
|
||||
* @return
|
||||
*/
|
||||
Entity getEntity(String entityName, String entityType);
|
||||
}
|
@ -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";
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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}
|
||||
*/
|
||||
|
@ -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 <code>false</code>
|
||||
*/
|
||||
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}
|
||||
*/
|
||||
|
@ -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 <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
* @see NacosConfigurationProperties
|
||||
|
@ -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 <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
* @see NacosConfigurationProperties
|
||||
|
@ -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,
|
||||
|
@ -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> {
|
||||
*/
|
||||
T convert(String config);
|
||||
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -24,7 +24,7 @@ import com.alibaba.nacos.api.exception.NacosException;
|
||||
*/
|
||||
public interface IConfigFilterChain {
|
||||
/**
|
||||
* filter aciton
|
||||
* Filter aciton
|
||||
*
|
||||
* @param request request
|
||||
* @param response response
|
||||
|
@ -30,7 +30,7 @@ public interface IConfigResponse {
|
||||
Object getParameter(String key);
|
||||
|
||||
/**
|
||||
* get config context
|
||||
* Get config context
|
||||
*
|
||||
* @return configContext
|
||||
*/
|
||||
|
@ -30,7 +30,7 @@ public interface IFilterConfig {
|
||||
String getFilterName();
|
||||
|
||||
/**
|
||||
* get init param
|
||||
* Get init param
|
||||
*
|
||||
* @param name
|
||||
* @return param
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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;
|
||||
|
||||
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<String> 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<String> getServicesOfServer(int pageNo, int pageSize, AbstractSelector selector) throws NacosException;
|
||||
|
||||
/**
|
||||
* Get all subscribed services of current client
|
||||
>>>>>>> upstream/develop
|
||||
*
|
||||
* @return subscribed services
|
||||
* @throws NacosException
|
||||
|
@ -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 <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||
*/
|
||||
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<String, String> getCustomHeaders() {
|
||||
if (StringUtils.isBlank(headers)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
Map<String, String> headerMap = new HashMap<String, String>(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) {
|
||||
|
@ -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<String, String> metadata = new HashMap<String, String>();
|
||||
|
||||
public Cluster() {
|
||||
|
@ -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<String, String> 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());
|
||||
}
|
||||
|
@ -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<String, String> metadata = new HashMap<String, String>();
|
||||
|
||||
public Service(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
private Map<String, String> metadata = new HashMap<String, String>();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
@ -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 <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
@ -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 <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||
*/
|
||||
public enum SelectorType {
|
||||
/**
|
||||
* not match any type
|
||||
*/
|
||||
unknown,
|
||||
/**
|
||||
* not filter out any entity
|
||||
*/
|
||||
none,
|
||||
/**
|
||||
* select by label
|
||||
*/
|
||||
label
|
||||
}
|
@ -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,
|
||||
|
185
client/pom.xml
185
client/pom.xml
@ -12,113 +12,100 @@
|
||||
limitations under the License.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-all</artifactId>
|
||||
<version>0.2.1</version>
|
||||
</parent>
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-all</artifactId>
|
||||
<version>0.7.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>nacos-client</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<artifactId>nacos-client</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>nacos-client ${project.version}</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
<name>nacos-client ${project.version}</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>2.8.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-slf4j-impl</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>nacos-common</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>nacos-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
</dependency>
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>2.8.2</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<groupId>commons-codec</groupId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-slf4j-impl</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-mapper-lgpl</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.jcip</groupId>
|
||||
<artifactId>jcip-annotations</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.spotbugs</groupId>
|
||||
<artifactId>spotbugs-annotations</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>nacos-common</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>nacos-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<groupId>commons-codec</groupId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-mapper-lgpl</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.jcip</groupId>
|
||||
<artifactId>jcip-annotations</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.spotbugs</groupId>
|
||||
<artifactId>spotbugs-annotations</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
|
@ -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<String> params = new ArrayList<String>();
|
||||
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<String> params = new ArrayList<String>();
|
||||
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<String> params = new ArrayList<String>();
|
||||
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<String> params = new ArrayList<String>();
|
||||
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<String> headers = new ArrayList<String>();
|
||||
if (StringUtils.isNotEmpty(betaIps)) {
|
||||
headers.add("betaIps");
|
||||
headers.add(betaIps);
|
||||
}
|
||||
List<String> headers = new ArrayList<String>();
|
||||
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";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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<String, Object> param = new HashMap<String, Object>();
|
||||
private Map<String, Object> param = new HashMap<String, Object>();
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<IConfigFilter> filters = Lists.newArrayList();
|
||||
private List<IConfigFilter> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<String, Object> param = new HashMap<String, Object>();
|
||||
private Map<String, Object> param = new HashMap<String, Object>();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<String, Object> param = new HashMap<String, Object>();
|
||||
private Map<String, Object> param = new HashMap<String, Object>();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<ManagerListenerWrap>();
|
||||
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<ManagerListenerWrap>();
|
||||
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<ManagerListenerWrap>();
|
||||
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<ManagerListenerWrap>();
|
||||
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<ManagerListenerWrap> 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<String, CacheData> copy = new HashMap<String, CacheData>(cacheMap.get());
|
||||
copy.remove(groupKey);
|
||||
cacheMap.set(copy);
|
||||
}
|
||||
log.info(agent.getName(), "[unsubscribe] {}", groupKey);
|
||||
String groupKey = GroupKey.getKeyTenant(dataId, group, tenant);
|
||||
synchronized (cacheMap) {
|
||||
Map<String, CacheData> copy = new HashMap<String, CacheData>(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<String, CacheData> copy = new HashMap<String, CacheData>(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<String, CacheData> copy = new HashMap<String, CacheData>(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<String, CacheData> copy = new HashMap<String, CacheData>(cacheMap.get());
|
||||
copy.put(key, cache);
|
||||
cacheMap.set(copy);
|
||||
}
|
||||
log.info(agent.getName(), "[subscribe] {}", key);
|
||||
return cache;
|
||||
}
|
||||
|
||||
HttpResult result = null;
|
||||
try {
|
||||
List<String> 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<String> 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<String> checkUpdateDataIds(List<CacheData> cacheDatas, List<String> 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<String> checkUpdateConfigStr(String probeUpdateString, boolean isInitializingCacheList) {
|
||||
/**
|
||||
* 从Server获取值变化了的DataID列表。返回的对象里只有dataId和group是有效的。 保证不返回NULL。
|
||||
*/
|
||||
List<String> checkUpdateDataIds(List<CacheData> cacheDatas, List<String> 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<String> params = Arrays.asList(Constants.PROBE_MODIFY_REQUEST, probeUpdateString);
|
||||
long timeout = TimeUnit.SECONDS.toMillis(30L);
|
||||
/**
|
||||
* 从Server获取值变化了的DataID列表。返回的对象里只有dataId和group是有效的。 保证不返回NULL。
|
||||
*/
|
||||
List<String> checkUpdateConfigStr(String probeUpdateString, boolean isInitializingCacheList) {
|
||||
|
||||
List<String> headers = new ArrayList<String>(2);
|
||||
headers.add("Long-Pulling-Timeout");
|
||||
headers.add("" + timeout);
|
||||
List<String> 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<String> headers = new ArrayList<String>(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<String> 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<String> parseUpdateDataIdResponse(String response) {
|
||||
if (StringUtils.isBlank(response)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<String> updateList = new LinkedList<String>();
|
||||
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<String> updateList = new LinkedList<String>();
|
||||
|
||||
@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<CacheData> cacheDatas = new ArrayList<CacheData>();
|
||||
// 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<String> inInitializingCacheList = new ArrayList<String>();
|
||||
// check server config
|
||||
List<String> changedGroupKeys = checkUpdateDataIds(cacheDatas, inInitializingCacheList);
|
||||
public void run() {
|
||||
try {
|
||||
List<CacheData> cacheDatas = new ArrayList<CacheData>();
|
||||
// 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<String> inInitializingCacheList = new ArrayList<String>();
|
||||
// check server config
|
||||
List<String> 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<Map<String, CacheData>> cacheMap = new AtomicReference<Map<String, CacheData>>(
|
||||
new HashMap<String, CacheData>());
|
||||
ServerHttpAgent agent;
|
||||
ConfigFilterChainManager configFilterChainManager;
|
||||
private boolean isHealthServer = true;
|
||||
private double currentLongingTaskCount = 0;
|
||||
|
||||
final ScheduledExecutorService executor;
|
||||
final ExecutorService executorService;
|
||||
/**
|
||||
* groupKey -> cacheData
|
||||
*/
|
||||
AtomicReference<Map<String, CacheData>> cacheMap = new AtomicReference<Map<String, CacheData>>(new HashMap<String, CacheData>());
|
||||
ServerHttpAgent agent;
|
||||
ConfigFilterChainManager configFilterChainManager;
|
||||
private boolean isHealthServer = true;
|
||||
private double currentLongingTaskCount = 0;
|
||||
|
||||
}
|
||||
|
@ -24,16 +24,14 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import com.alibaba.nacos.client.config.utils.LogUtils;
|
||||
import com.alibaba.nacos.client.logger.Logger;
|
||||
|
||||
|
||||
/**
|
||||
* Event subscription and publishing tools.
|
||||
*
|
||||
* @author Nacos
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class EventDispatcher {
|
||||
|
||||
final static public Logger log = LogUtils.logger(EventDispatcher.class);
|
||||
|
||||
final static public Logger log = LogUtils.logger(EventDispatcher.class);
|
||||
|
||||
/**
|
||||
* 添加事件监听器
|
||||
@ -55,7 +53,7 @@ public class EventDispatcher {
|
||||
// 发布该事件暗示的其他事件
|
||||
for (AbstractEvent implyEvent : abstractEvent.implyEvents()) {
|
||||
try {
|
||||
// 避免死循环
|
||||
// 避免死循环
|
||||
if (abstractEvent != implyEvent) {
|
||||
fireEvent(implyEvent);
|
||||
}
|
||||
@ -74,7 +72,7 @@ public class EventDispatcher {
|
||||
}
|
||||
|
||||
static synchronized CopyOnWriteArrayList<AbstractEventListener> getListenerList(
|
||||
Class<? extends AbstractEvent> eventType) {
|
||||
Class<? extends AbstractEvent> eventType) {
|
||||
CopyOnWriteArrayList<AbstractEventListener> listeners = LISTENER_MAP.get(eventType);
|
||||
if (null == listeners) {
|
||||
listeners = new CopyOnWriteArrayList<AbstractEventListener>();
|
||||
@ -84,8 +82,9 @@ public class EventDispatcher {
|
||||
}
|
||||
|
||||
// ========================
|
||||
|
||||
static final Map<Class<? extends AbstractEvent>, CopyOnWriteArrayList<AbstractEventListener>> LISTENER_MAP = new HashMap<Class<? extends AbstractEvent>, CopyOnWriteArrayList<AbstractEventListener>>();
|
||||
|
||||
static final Map<Class<? extends AbstractEvent>, CopyOnWriteArrayList<AbstractEventListener>> LISTENER_MAP
|
||||
= new HashMap<Class<? extends AbstractEvent>, CopyOnWriteArrayList<AbstractEventListener>>();
|
||||
|
||||
// ========================
|
||||
|
||||
@ -105,29 +104,30 @@ public class EventDispatcher {
|
||||
*/
|
||||
static public abstract class AbstractEventListener {
|
||||
public AbstractEventListener() {
|
||||
/**
|
||||
* 自动注册给EventDispatcher
|
||||
*/
|
||||
EventDispatcher.addEventListener(this);
|
||||
/**
|
||||
* 自动注册给EventDispatcher
|
||||
*/
|
||||
EventDispatcher.addEventListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 感兴趣的事件列表
|
||||
*
|
||||
* @return event list
|
||||
*/
|
||||
|
||||
/**
|
||||
* 感兴趣的事件列表
|
||||
*
|
||||
* @return event list
|
||||
*/
|
||||
abstract public List<Class<? extends AbstractEvent>> interest();
|
||||
|
||||
/**
|
||||
* 处理事件
|
||||
*
|
||||
* @param abstractEvent event to do
|
||||
*/
|
||||
abstract public void onEvent(AbstractEvent abstractEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* serverList has changed
|
||||
*/
|
||||
static public class ServerlistChangeEvent extends AbstractEvent {
|
||||
}
|
||||
/**
|
||||
* serverList has changed
|
||||
*/
|
||||
static public class ServerlistChangeEvent extends AbstractEvent {
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.alibaba.nacos.client.config.utils.IOUtils;
|
||||
import com.alibaba.nacos.client.config.utils.MD5;
|
||||
import com.alibaba.nacos.client.utils.ParamUtil;
|
||||
import com.alibaba.nacos.common.util.UuidUtil;
|
||||
import com.alibaba.nacos.common.util.UuidUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
@ -34,95 +34,88 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* Http tool
|
||||
*
|
||||
*
|
||||
* @author Nacos
|
||||
*
|
||||
*/
|
||||
public class HttpSimpleClient {
|
||||
|
||||
|
||||
static public HttpResult httpGet(String url, List<String> headers, List<String> paramValues,
|
||||
String encoding, long readTimeoutMs, boolean isSSL) throws IOException{
|
||||
String encodedContent = encodingParams(paramValues, encoding);
|
||||
String encoding, long readTimeoutMs, boolean isSSL) throws IOException {
|
||||
String encodedContent = encodingParams(paramValues, encoding);
|
||||
url += (null == encodedContent) ? "" : ("?" + encodedContent);
|
||||
if (Limiter.isLimit(MD5.getInstance().getMD5String(
|
||||
new StringBuilder(url).append(encodedContent).toString()))) {
|
||||
return new HttpResult(NacosException.CLIENT_OVER_THRESHOLD,
|
||||
"More than client-side current limit threshold");
|
||||
}
|
||||
|
||||
if (Limiter.isLimit(MD5.getInstance().getMD5String(
|
||||
new StringBuilder(url).append(encodedContent).toString()))) {
|
||||
return new HttpResult(NacosException.CLIENT_OVER_THRESHOLD,
|
||||
"More than client-side current limit threshold");
|
||||
}
|
||||
|
||||
HttpURLConnection conn = null;
|
||||
|
||||
try {
|
||||
conn = (HttpURLConnection) new URL(url).openConnection();
|
||||
conn.setRequestMethod("GET");
|
||||
conn.setConnectTimeout(ParamUtil.getConnectTimeout() > 100 ? ParamUtil.getConnectTimeout() : 100);
|
||||
conn.setReadTimeout((int) readTimeoutMs);
|
||||
List<String> newHeaders = getHeaders(url, headers, paramValues);
|
||||
setHeaders(conn, newHeaders, encoding);
|
||||
|
||||
conn.connect();
|
||||
|
||||
int respCode = conn.getResponseCode();
|
||||
String resp = null;
|
||||
try {
|
||||
conn = (HttpURLConnection)new URL(url).openConnection();
|
||||
conn.setRequestMethod("GET");
|
||||
conn.setConnectTimeout(ParamUtil.getConnectTimeout() > 100 ? ParamUtil.getConnectTimeout() : 100);
|
||||
conn.setReadTimeout((int)readTimeoutMs);
|
||||
List<String> newHeaders = getHeaders(url, headers, paramValues);
|
||||
setHeaders(conn, newHeaders, encoding);
|
||||
|
||||
if (HttpURLConnection.HTTP_OK == respCode) {
|
||||
resp = IOUtils.toString(conn.getInputStream(), encoding);
|
||||
} else {
|
||||
resp = IOUtils.toString(conn.getErrorStream(), encoding);
|
||||
}
|
||||
return new HttpResult(respCode, conn.getHeaderFields(), resp);
|
||||
} finally {
|
||||
conn.connect();
|
||||
|
||||
int respCode = conn.getResponseCode();
|
||||
String resp = null;
|
||||
|
||||
if (HttpURLConnection.HTTP_OK == respCode) {
|
||||
resp = IOUtils.toString(conn.getInputStream(), encoding);
|
||||
} else {
|
||||
resp = IOUtils.toString(conn.getErrorStream(), encoding);
|
||||
}
|
||||
return new HttpResult(respCode, conn.getHeaderFields(), resp);
|
||||
} finally {
|
||||
if (conn != null) {
|
||||
conn.disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 发送GET请求。
|
||||
*/
|
||||
static public HttpResult httpGet(String url, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs) throws IOException {
|
||||
return httpGet(url, headers, paramValues, encoding, readTimeoutMs, false);
|
||||
}
|
||||
/**
|
||||
* 发送GET请求。
|
||||
*/
|
||||
static public HttpResult httpGet(String url, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs) throws IOException {
|
||||
return httpGet(url, headers, paramValues, encoding, readTimeoutMs, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送POST请求。
|
||||
*
|
||||
*
|
||||
* @param url
|
||||
* @param headers
|
||||
* 请求Header,可以为null
|
||||
* @param paramValues
|
||||
* 参数,可以为null
|
||||
* @param encoding
|
||||
* URL编码使用的字符集
|
||||
* @param readTimeoutMs
|
||||
* 响应超时
|
||||
* @param isSSL
|
||||
* 是否https
|
||||
* @param headers 请求Header,可以为null
|
||||
* @param paramValues 参数,可以为null
|
||||
* @param encoding URL编码使用的字符集
|
||||
* @param readTimeoutMs 响应超时
|
||||
* @param isSSL 是否https
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
static public HttpResult httpPost(String url, List<String> headers, List<String> paramValues,
|
||||
String encoding, long readTimeoutMs, boolean isSSL) throws IOException {
|
||||
String encodedContent = encodingParams(paramValues, encoding);
|
||||
if (Limiter.isLimit(MD5.getInstance().getMD5String(
|
||||
new StringBuilder(url).append(encodedContent).toString()))) {
|
||||
return new HttpResult(NacosException.CLIENT_OVER_THRESHOLD,
|
||||
"More than client-side current limit threshold");
|
||||
}
|
||||
String encoding, long readTimeoutMs, boolean isSSL) throws IOException {
|
||||
String encodedContent = encodingParams(paramValues, encoding);
|
||||
if (Limiter.isLimit(MD5.getInstance().getMD5String(
|
||||
new StringBuilder(url).append(encodedContent).toString()))) {
|
||||
return new HttpResult(NacosException.CLIENT_OVER_THRESHOLD,
|
||||
"More than client-side current limit threshold");
|
||||
}
|
||||
HttpURLConnection conn = null;
|
||||
try {
|
||||
conn = (HttpURLConnection) new URL(url).openConnection();
|
||||
conn = (HttpURLConnection)new URL(url).openConnection();
|
||||
conn.setRequestMethod("POST");
|
||||
conn.setConnectTimeout(ParamUtil.getConnectTimeout() > 3000 ? ParamUtil.getConnectTimeout() : 3000);
|
||||
conn.setReadTimeout((int) readTimeoutMs);
|
||||
conn.setReadTimeout((int)readTimeoutMs);
|
||||
conn.setDoOutput(true);
|
||||
conn.setDoInput(true);
|
||||
List<String> newHeaders = getHeaders(url, headers, paramValues);
|
||||
setHeaders(conn, newHeaders, encoding);
|
||||
List<String> newHeaders = getHeaders(url, headers, paramValues);
|
||||
setHeaders(conn, newHeaders, encoding);
|
||||
|
||||
conn.getOutputStream().write(encodedContent.getBytes(encoding));
|
||||
|
||||
@ -141,81 +134,75 @@ public class HttpSimpleClient {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送POST请求。
|
||||
*
|
||||
* @param url
|
||||
* @param headers
|
||||
* 请求Header,可以为null
|
||||
* @param paramValues
|
||||
* 参数,可以为null
|
||||
* @param encoding
|
||||
* URL编码使用的字符集
|
||||
* @param readTimeoutMs
|
||||
* 响应超时
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
static public HttpResult httpPost(String url, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs) throws IOException {
|
||||
return httpPost(url, headers, paramValues, encoding, readTimeoutMs, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 发送POST请求。
|
||||
*
|
||||
* @param url
|
||||
* @param headers 请求Header,可以为null
|
||||
* @param paramValues 参数,可以为null
|
||||
* @param encoding URL编码使用的字符集
|
||||
* @param readTimeoutMs 响应超时
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
static public HttpResult httpPost(String url, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs) throws IOException {
|
||||
return httpPost(url, headers, paramValues, encoding, readTimeoutMs, false);
|
||||
}
|
||||
|
||||
static public HttpResult httpDelete(String url, List<String> headers, List<String> paramValues,
|
||||
String encoding, long readTimeoutMs, boolean isSSL) throws IOException{
|
||||
String encodedContent = encodingParams(paramValues, encoding);
|
||||
String encoding, long readTimeoutMs, boolean isSSL) throws IOException {
|
||||
String encodedContent = encodingParams(paramValues, encoding);
|
||||
url += (null == encodedContent) ? "" : ("?" + encodedContent);
|
||||
if (Limiter.isLimit(MD5.getInstance().getMD5String(
|
||||
new StringBuilder(url).append(encodedContent).toString()))) {
|
||||
return new HttpResult(NacosException.CLIENT_OVER_THRESHOLD,
|
||||
"More than client-side current limit threshold");
|
||||
}
|
||||
|
||||
if (Limiter.isLimit(MD5.getInstance().getMD5String(
|
||||
new StringBuilder(url).append(encodedContent).toString()))) {
|
||||
return new HttpResult(NacosException.CLIENT_OVER_THRESHOLD,
|
||||
"More than client-side current limit threshold");
|
||||
}
|
||||
|
||||
HttpURLConnection conn = null;
|
||||
|
||||
try {
|
||||
conn = (HttpURLConnection) new URL(url).openConnection();
|
||||
conn.setRequestMethod("DELETE");
|
||||
conn.setConnectTimeout(ParamUtil.getConnectTimeout() > 100 ? ParamUtil.getConnectTimeout() : 100);
|
||||
conn.setReadTimeout((int) readTimeoutMs);
|
||||
List<String> newHeaders = getHeaders(url, headers, paramValues);
|
||||
setHeaders(conn, newHeaders, encoding);
|
||||
|
||||
conn.connect();
|
||||
|
||||
int respCode = conn.getResponseCode();
|
||||
String resp = null;
|
||||
try {
|
||||
conn = (HttpURLConnection)new URL(url).openConnection();
|
||||
conn.setRequestMethod("DELETE");
|
||||
conn.setConnectTimeout(ParamUtil.getConnectTimeout() > 100 ? ParamUtil.getConnectTimeout() : 100);
|
||||
conn.setReadTimeout((int)readTimeoutMs);
|
||||
List<String> newHeaders = getHeaders(url, headers, paramValues);
|
||||
setHeaders(conn, newHeaders, encoding);
|
||||
|
||||
if (HttpURLConnection.HTTP_OK == respCode) {
|
||||
resp = IOUtils.toString(conn.getInputStream(), encoding);
|
||||
} else {
|
||||
resp = IOUtils.toString(conn.getErrorStream(), encoding);
|
||||
}
|
||||
return new HttpResult(respCode, conn.getHeaderFields(), resp);
|
||||
} finally {
|
||||
conn.connect();
|
||||
|
||||
int respCode = conn.getResponseCode();
|
||||
String resp = null;
|
||||
|
||||
if (HttpURLConnection.HTTP_OK == respCode) {
|
||||
resp = IOUtils.toString(conn.getInputStream(), encoding);
|
||||
} else {
|
||||
resp = IOUtils.toString(conn.getErrorStream(), encoding);
|
||||
}
|
||||
return new HttpResult(respCode, conn.getHeaderFields(), resp);
|
||||
} finally {
|
||||
if (conn != null) {
|
||||
conn.disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static public HttpResult httpDelete(String url, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs) throws IOException {
|
||||
return httpGet(url, headers, paramValues, encoding, readTimeoutMs, false);
|
||||
}
|
||||
|
||||
static public HttpResult httpDelete(String url, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs) throws IOException {
|
||||
return httpGet(url, headers, paramValues, encoding, readTimeoutMs, false);
|
||||
}
|
||||
|
||||
static private void setHeaders(HttpURLConnection conn, List<String> headers, String encoding) {
|
||||
if (null != headers) {
|
||||
for (Iterator<String> iter = headers.iterator(); iter.hasNext();) {
|
||||
for (Iterator<String> iter = headers.iterator(); iter.hasNext(); ) {
|
||||
conn.addRequestProperty(iter.next(), iter.next());
|
||||
}
|
||||
}
|
||||
conn.addRequestProperty("Client-Version", ParamUtil.getClientVersion());
|
||||
conn.addRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + encoding);
|
||||
|
||||
|
||||
String ts = String.valueOf(System.currentTimeMillis());
|
||||
String token = MD5.getInstance().getMD5String(ts + ParamUtil.getAppKey());
|
||||
|
||||
@ -224,27 +211,27 @@ public class HttpSimpleClient {
|
||||
conn.addRequestProperty(Constants.CLIENT_REQUEST_TOKEN_HEADER, token);
|
||||
}
|
||||
|
||||
private static List<String> getHeaders(String url, List<String> headers, List<String> paramValues)
|
||||
throws IOException {
|
||||
List<String> newHeaders = new ArrayList<String>();
|
||||
newHeaders.add("exConfigInfo");
|
||||
newHeaders.add("true");
|
||||
newHeaders.add("RequestId");
|
||||
newHeaders.add(UuidUtil.generateUuid());
|
||||
if (headers!=null) {
|
||||
newHeaders.addAll(headers);
|
||||
}
|
||||
return newHeaders;
|
||||
}
|
||||
|
||||
private static List<String> getHeaders(String url, List<String> headers, List<String> paramValues)
|
||||
throws IOException {
|
||||
List<String> newHeaders = new ArrayList<String>();
|
||||
newHeaders.add("exConfigInfo");
|
||||
newHeaders.add("true");
|
||||
newHeaders.add("RequestId");
|
||||
newHeaders.add(UuidUtils.generateUuid());
|
||||
if (headers != null) {
|
||||
newHeaders.addAll(headers);
|
||||
}
|
||||
return newHeaders;
|
||||
}
|
||||
|
||||
static private String encodingParams(List<String> paramValues, String encoding)
|
||||
throws UnsupportedEncodingException {
|
||||
throws UnsupportedEncodingException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (null == paramValues) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (Iterator<String> iter = paramValues.iterator(); iter.hasNext();) {
|
||||
|
||||
for (Iterator<String> iter = paramValues.iterator(); iter.hasNext(); ) {
|
||||
sb.append(iter.next()).append("=");
|
||||
sb.append(URLEncoder.encode(iter.next(), encoding));
|
||||
if (iter.hasNext()) {
|
||||
@ -253,23 +240,23 @@ public class HttpSimpleClient {
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
static public class HttpResult {
|
||||
final public int code;
|
||||
final public Map<String,List<String>> headers;
|
||||
final public Map<String, List<String>> headers;
|
||||
final public String content;
|
||||
|
||||
public HttpResult(int code, String content) {
|
||||
this.code = code;
|
||||
this.headers = null;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public HttpResult(int code, Map<String, List<String>> headers, String content) {
|
||||
this.code = code;
|
||||
this.headers = headers;
|
||||
this.content = content;
|
||||
}
|
||||
public HttpResult(int code, String content) {
|
||||
this.code = code;
|
||||
this.headers = null;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public HttpResult(int code, Map<String, List<String>> headers, String content) {
|
||||
this.code = code;
|
||||
this.headers = headers;
|
||||
this.content = content;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -27,53 +27,52 @@ import com.google.common.util.concurrent.RateLimiter;
|
||||
|
||||
/**
|
||||
* Limiter
|
||||
*
|
||||
* @author Nacos
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class Limiter {
|
||||
|
||||
static final public Logger log = LogUtils.logger(Limiter.class);
|
||||
private static int CAPACITY_SIZE = 1000;
|
||||
private static int LIMIT_TIME = 1000;
|
||||
private static Cache<String, RateLimiter> cache = CacheBuilder.newBuilder()
|
||||
.initialCapacity(CAPACITY_SIZE).expireAfterAccess(1, TimeUnit.MINUTES)
|
||||
.build();
|
||||
static final public Logger log = LogUtils.logger(Limiter.class);
|
||||
private static int CAPACITY_SIZE = 1000;
|
||||
private static int LIMIT_TIME = 1000;
|
||||
private static Cache<String, RateLimiter> cache = CacheBuilder.newBuilder()
|
||||
.initialCapacity(CAPACITY_SIZE).expireAfterAccess(1, TimeUnit.MINUTES)
|
||||
.build();
|
||||
|
||||
/**
|
||||
* qps 5
|
||||
*/
|
||||
private static final String DEFAULT_LIMIT = "5";
|
||||
private static double limit = 5;
|
||||
/**
|
||||
* qps 5
|
||||
*/
|
||||
private static final String DEFAULT_LIMIT = "5";
|
||||
private static double limit = 5;
|
||||
|
||||
static {
|
||||
try {
|
||||
String limitTimeStr = System
|
||||
.getProperty("limitTime", DEFAULT_LIMIT);
|
||||
limit = Double.parseDouble(limitTimeStr);
|
||||
log.info("limitTime:{}", limit);
|
||||
} catch (Exception e) {
|
||||
log.error("Nacos-xxx", "init limitTime fail", e);
|
||||
}
|
||||
}
|
||||
static {
|
||||
try {
|
||||
String limitTimeStr = System
|
||||
.getProperty("limitTime", DEFAULT_LIMIT);
|
||||
limit = Double.parseDouble(limitTimeStr);
|
||||
log.info("limitTime:{}", limit);
|
||||
} catch (Exception e) {
|
||||
log.error("Nacos-xxx", "init limitTime fail", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isLimit(String accessKeyID) {
|
||||
RateLimiter rateLimiter = null;
|
||||
try {
|
||||
rateLimiter = cache.get(accessKeyID, new Callable<RateLimiter>() {
|
||||
@Override
|
||||
public RateLimiter call() throws Exception {
|
||||
return RateLimiter.create(limit);
|
||||
}
|
||||
});
|
||||
} catch (ExecutionException e) {
|
||||
log.error("Nacos-XXX", "create limit fail", e);
|
||||
}
|
||||
if (rateLimiter != null && !rateLimiter.tryAcquire(LIMIT_TIME, TimeUnit.MILLISECONDS)) {
|
||||
log.error("Nacos-XXX", "access_key_id:{} limited", accessKeyID);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static boolean isLimit(String accessKeyID) {
|
||||
RateLimiter rateLimiter = null;
|
||||
try {
|
||||
rateLimiter = cache.get(accessKeyID, new Callable<RateLimiter>() {
|
||||
@Override
|
||||
public RateLimiter call() throws Exception {
|
||||
return RateLimiter.create(limit);
|
||||
}
|
||||
});
|
||||
} catch (ExecutionException e) {
|
||||
log.error("Nacos-XXX", "create limit fail", e);
|
||||
}
|
||||
if (rateLimiter != null && !rateLimiter.tryAcquire(LIMIT_TIME, TimeUnit.MILLISECONDS)) {
|
||||
log.error("Nacos-XXX", "access_key_id:{} limited", accessKeyID);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,169 +25,170 @@ import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
|
||||
/**
|
||||
* Local Disaster Recovery Directory Tool
|
||||
*
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class LocalConfigInfoProcessor {
|
||||
|
||||
final static public Logger log = LogUtils.logger(LocalConfigInfoProcessor.class);
|
||||
|
||||
final static public Logger log = LogUtils.logger(LocalConfigInfoProcessor.class);
|
||||
|
||||
static public String getFailover(String serverName, String dataId, String group, String tenant) {
|
||||
File localPath = getFailoverFile(serverName, dataId, group, tenant);
|
||||
if (!localPath.exists() || !localPath.isFile()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return readFile(localPath);
|
||||
} catch (IOException ioe) {
|
||||
log.error(serverName, "NACOS-XXXX","get failover error, " + localPath + ioe.toString());
|
||||
return null;
|
||||
}
|
||||
File localPath = getFailoverFile(serverName, dataId, group, tenant);
|
||||
if (!localPath.exists() || !localPath.isFile()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return readFile(localPath);
|
||||
} catch (IOException ioe) {
|
||||
log.error(serverName, "NACOS-XXXX", "get failover error, " + localPath + ioe.toString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取本地缓存文件内容。NULL表示没有本地文件或抛出异常。
|
||||
*/
|
||||
static public String getSnapshot(String name, String dataId, String group, String tenant) {
|
||||
if (!SnapShotSwitch.getIsSnapShot()) {
|
||||
return null;
|
||||
}
|
||||
File file = getSnapshotFile(name, dataId, group, tenant);
|
||||
if (!file.exists() || !file.isFile()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return readFile(file);
|
||||
} catch (IOException ioe) {
|
||||
log.error(name, "NACOS-XXXX","get snapshot error, " + file + ", " + ioe.toString());
|
||||
return null;
|
||||
}
|
||||
if (!SnapShotSwitch.getIsSnapShot()) {
|
||||
return null;
|
||||
}
|
||||
File file = getSnapshotFile(name, dataId, group, tenant);
|
||||
if (!file.exists() || !file.isFile()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return readFile(file);
|
||||
} catch (IOException ioe) {
|
||||
log.error(name, "NACOS-XXXX", "get snapshot error, " + file + ", " + ioe.toString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static private String readFile(File file) throws IOException {
|
||||
if (!file.exists() || !file.isFile()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (JVMUtil.isMultiInstance()) {
|
||||
return ConcurrentDiskUtil.getFileContent(file, Constants.ENCODE);
|
||||
} else {
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = new FileInputStream(file);
|
||||
return IOUtils.toString(is, Constants.ENCODE);
|
||||
} finally {
|
||||
try {
|
||||
if (null != is) {
|
||||
is.close();
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
static private String readFile(File file) throws IOException {
|
||||
if (!file.exists() || !file.isFile()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (JVMUtil.isMultiInstance()) {
|
||||
return ConcurrentDiskUtil.getFileContent(file, Constants.ENCODE);
|
||||
} else {
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = new FileInputStream(file);
|
||||
return IOUtils.toString(is, Constants.ENCODE);
|
||||
} finally {
|
||||
try {
|
||||
if (null != is) {
|
||||
is.close();
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static public void saveSnapshot(String envName, String dataId, String group, String tenant, String config) {
|
||||
if (!SnapShotSwitch.getIsSnapShot()) {
|
||||
return;
|
||||
}
|
||||
if (!SnapShotSwitch.getIsSnapShot()) {
|
||||
return;
|
||||
}
|
||||
File file = getSnapshotFile(envName, dataId, group, tenant);
|
||||
if (null == config) {
|
||||
try {
|
||||
IOUtils.delete(file);
|
||||
} catch (IOException ioe) {
|
||||
log.error(envName, "NACOS-XXXX","delete snapshot error, " + file + ", " + ioe.toString());
|
||||
log.error(envName, "NACOS-XXXX", "delete snapshot error, " + file + ", " + ioe.toString());
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
boolean isMdOk = file.getParentFile().mkdirs();
|
||||
if (!isMdOk) {
|
||||
log.error(envName, "NACOS-XXXX", "save snapshot error");
|
||||
}
|
||||
if (JVMUtil.isMultiInstance()) {
|
||||
ConcurrentDiskUtil.writeFileContent(file, config,
|
||||
Constants.ENCODE);
|
||||
} else {
|
||||
IOUtils.writeStringToFile(file, config, Constants.ENCODE);
|
||||
}
|
||||
File parentFile = file.getParentFile();
|
||||
if (!parentFile.exists()) {
|
||||
boolean isMdOk = parentFile.mkdirs();
|
||||
if (!isMdOk) {
|
||||
log.error(envName, "NACOS-XXXX", "save snapshot error");
|
||||
}
|
||||
}
|
||||
|
||||
if (JVMUtil.isMultiInstance()) {
|
||||
ConcurrentDiskUtil.writeFileContent(file, config,
|
||||
Constants.ENCODE);
|
||||
} else {
|
||||
IOUtils.writeStringToFile(file, config, Constants.ENCODE);
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
log.error(envName, "NACOS-XXXX","save snapshot error, " + file + ", " + ioe.toString());
|
||||
log.error(envName, "NACOS-XXXX", "save snapshot error, " + file + ", " + ioe.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 清除snapshot目录下所有缓存文件。
|
||||
*/
|
||||
static public void cleanAllSnapshot() {
|
||||
try {
|
||||
File rootFile = new File(LOCAL_SNAPSHOT_PATH);
|
||||
File[] files = rootFile.listFiles();
|
||||
if (files == null || files.length == 0) {
|
||||
return;
|
||||
}
|
||||
for(File file : files){
|
||||
if(file.getName().endsWith("_nacos")){
|
||||
IOUtils.cleanDirectory(file);
|
||||
}
|
||||
}
|
||||
File rootFile = new File(LOCAL_SNAPSHOT_PATH);
|
||||
File[] files = rootFile.listFiles();
|
||||
if (files == null || files.length == 0) {
|
||||
return;
|
||||
}
|
||||
for (File file : files) {
|
||||
if (file.getName().endsWith("_nacos")) {
|
||||
IOUtils.cleanDirectory(file);
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
log.error("NACOS-XXXX","clean all snapshot error, " + ioe.toString(), ioe);
|
||||
log.error("NACOS-XXXX", "clean all snapshot error, " + ioe.toString(), ioe);
|
||||
}
|
||||
}
|
||||
|
||||
static public void cleanEnvSnapshot(String envName){
|
||||
File tmp = new File(LOCAL_SNAPSHOT_PATH, envName + "_nacos");
|
||||
tmp = new File(tmp, "snapshot");
|
||||
try {
|
||||
IOUtils.cleanDirectory(tmp);
|
||||
log.info("success dlelet " + envName + "-snapshot");
|
||||
} catch (IOException e) {
|
||||
log.info("fail dlelet " + envName + "-snapshot, " + e.toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
static public void cleanEnvSnapshot(String envName) {
|
||||
File tmp = new File(LOCAL_SNAPSHOT_PATH, envName + "_nacos");
|
||||
tmp = new File(tmp, "snapshot");
|
||||
try {
|
||||
IOUtils.cleanDirectory(tmp);
|
||||
log.info("success delete " + envName + "-snapshot");
|
||||
} catch (IOException e) {
|
||||
log.info("fail delete " + envName + "-snapshot, " + e.toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static File getFailoverFile(String serverName, String dataId, String group, String tenant) {
|
||||
File tmp = new File(LOCAL_SNAPSHOT_PATH, serverName + "_nacos");
|
||||
tmp = new File(tmp, "data");
|
||||
if (StringUtils.isBlank(tenant)) {
|
||||
tmp = new File(tmp, "config-data");
|
||||
} else
|
||||
{
|
||||
tmp = new File(tmp, "config-data-tenant");
|
||||
tmp = new File(tmp, tenant);
|
||||
}
|
||||
return new File(new File(tmp, group), dataId);
|
||||
}
|
||||
|
||||
static File getSnapshotFile(String envName, String dataId, String group, String tenant) {
|
||||
File tmp = new File(LOCAL_SNAPSHOT_PATH, envName + "_nacos");
|
||||
if (StringUtils.isBlank(tenant)) {
|
||||
tmp = new File(tmp, "snapshot");
|
||||
} else {
|
||||
tmp = new File(tmp, "snapshot-tenant");
|
||||
tmp = new File(tmp, tenant);
|
||||
}
|
||||
|
||||
File tmp = new File(LOCAL_SNAPSHOT_PATH, serverName + "_nacos");
|
||||
tmp = new File(tmp, "data");
|
||||
if (StringUtils.isBlank(tenant)) {
|
||||
tmp = new File(tmp, "config-data");
|
||||
} else {
|
||||
tmp = new File(tmp, "config-data-tenant");
|
||||
tmp = new File(tmp, tenant);
|
||||
}
|
||||
return new File(new File(tmp, group), dataId);
|
||||
}
|
||||
|
||||
|
||||
static File getSnapshotFile(String envName, String dataId, String group, String tenant) {
|
||||
File tmp = new File(LOCAL_SNAPSHOT_PATH, envName + "_nacos");
|
||||
if (StringUtils.isBlank(tenant)) {
|
||||
tmp = new File(tmp, "snapshot");
|
||||
} else {
|
||||
tmp = new File(tmp, "snapshot-tenant");
|
||||
tmp = new File(tmp, tenant);
|
||||
}
|
||||
|
||||
return new File(new File(tmp, group), dataId);
|
||||
}
|
||||
|
||||
public static final String LOCAL_FILEROOT_PATH;
|
||||
public static final String LOCAL_SNAPSHOT_PATH;
|
||||
static {
|
||||
LOCAL_FILEROOT_PATH = System.getProperty("JM.LOG.PATH", System.getProperty("user.home")) + File.separator
|
||||
+ "nacos" + File.separator + "config";
|
||||
LOCAL_SNAPSHOT_PATH = System.getProperty("JM.SNAPSHOT.PATH", System.getProperty("user.home")) + File.separator
|
||||
+ "nacos" + File.separator + "config";
|
||||
log.warn("LOCAL_SNAPSHOT_PATH:{}", LOCAL_SNAPSHOT_PATH);
|
||||
}
|
||||
|
||||
static {
|
||||
LOCAL_FILEROOT_PATH = System.getProperty("JM.LOG.PATH", System.getProperty("user.home")) + File.separator
|
||||
+ "nacos" + File.separator + "config";
|
||||
LOCAL_SNAPSHOT_PATH = System.getProperty("JM.SNAPSHOT.PATH", System.getProperty("user.home")) + File.separator
|
||||
+ "nacos" + File.separator + "config";
|
||||
log.warn("LOCAL_SNAPSHOT_PATH:{}", LOCAL_SNAPSHOT_PATH);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -41,351 +41,352 @@ import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Server Agent
|
||||
*
|
||||
* @author water.lyl
|
||||
* Server Agent
|
||||
*
|
||||
* @author water.lyl
|
||||
*/
|
||||
public class ServerHttpAgent {
|
||||
|
||||
final static public Logger log = LogUtils.logger(ServerHttpAgent.class);
|
||||
/**
|
||||
* @param path
|
||||
* 相对于web应用根,以/开头
|
||||
* @param headers
|
||||
* @param paramValues
|
||||
* @param encoding
|
||||
* @param readTimeoutMs
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public HttpResult httpGet(String path, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs) throws IOException {
|
||||
final long endTime = System.currentTimeMillis() + readTimeoutMs;
|
||||
final static public Logger log = LogUtils.logger(ServerHttpAgent.class);
|
||||
|
||||
boolean isSSL = false;
|
||||
|
||||
do {
|
||||
try {
|
||||
List<String> newHeaders = getSpasHeaders(paramValues);
|
||||
if (headers != null) {
|
||||
newHeaders.addAll(headers);
|
||||
}
|
||||
HttpResult result = HttpSimpleClient.httpGet(
|
||||
getUrl(serverListMgr.getCurrentServerAddr(), path, isSSL), newHeaders, paramValues, encoding,
|
||||
readTimeoutMs, isSSL);
|
||||
if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR
|
||||
|| result.code == HttpURLConnection.HTTP_BAD_GATEWAY
|
||||
|| result.code == HttpURLConnection.HTTP_UNAVAILABLE) {
|
||||
log.error("NACOS ConnectException", "currentServerAddr:{}. httpCode:",
|
||||
new Object[] { serverListMgr.getCurrentServerAddr(), result.code });
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
} catch (ConnectException ce) {
|
||||
log.error("NACOS ConnectException", "currentServerAddr:{}",
|
||||
new Object[] { serverListMgr.getCurrentServerAddr() });
|
||||
serverListMgr.refreshCurrentServerAddr();
|
||||
} catch (SocketTimeoutException stoe) {
|
||||
log.error("NACOS SocketTimeoutException", "currentServerAddr:{}",
|
||||
new Object[] { serverListMgr.getCurrentServerAddr()});
|
||||
serverListMgr.refreshCurrentServerAddr();
|
||||
} catch (IOException ioe) {
|
||||
log.error("NACOS IOException", "currentServerAddr:{}",
|
||||
new Object[] { serverListMgr.getCurrentServerAddr()});
|
||||
throw ioe;
|
||||
}
|
||||
} while (System.currentTimeMillis() <= endTime);
|
||||
/**
|
||||
* @param path 相对于web应用根,以/开头
|
||||
* @param headers
|
||||
* @param paramValues
|
||||
* @param encoding
|
||||
* @param readTimeoutMs
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public HttpResult httpGet(String path, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs) throws IOException {
|
||||
final long endTime = System.currentTimeMillis() + readTimeoutMs;
|
||||
|
||||
log.error("NACOS-0002",
|
||||
LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0002", "环境问题", "no available server"));
|
||||
throw new ConnectException("no available server");
|
||||
}
|
||||
boolean isSSL = false;
|
||||
|
||||
public HttpResult httpPost(String path, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs) throws IOException {
|
||||
final long endTime = System.currentTimeMillis() + readTimeoutMs;
|
||||
boolean isSSL = false;
|
||||
do {
|
||||
try {
|
||||
List<String> newHeaders = getSpasHeaders(paramValues);
|
||||
if (headers != null) {
|
||||
newHeaders.addAll(headers);
|
||||
}
|
||||
HttpResult result = HttpSimpleClient.httpPost(
|
||||
getUrl(serverListMgr.getCurrentServerAddr(), path, isSSL), newHeaders, paramValues, encoding,
|
||||
readTimeoutMs, isSSL);
|
||||
if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR
|
||||
|| result.code == HttpURLConnection.HTTP_BAD_GATEWAY
|
||||
|| result.code == HttpURLConnection.HTTP_UNAVAILABLE) {
|
||||
log.error("NACOS ConnectException", "currentServerAddr:{}. httpCode:",
|
||||
new Object[] { serverListMgr.getCurrentServerAddr(), result.code });
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
} catch (ConnectException ce) {
|
||||
log.error("NACOS ConnectException", "currentServerAddr:{}",
|
||||
new Object[] { serverListMgr.getCurrentServerAddr()});
|
||||
serverListMgr.refreshCurrentServerAddr();
|
||||
} catch (SocketTimeoutException stoe) {
|
||||
log.error("NACOS SocketTimeoutException", "currentServerAddr:{}",
|
||||
new Object[] { serverListMgr.getCurrentServerAddr()});
|
||||
serverListMgr.refreshCurrentServerAddr();
|
||||
} catch (IOException ioe) {
|
||||
log.error("NACOS IOException", "currentServerAddr:{}",
|
||||
new Object[] { serverListMgr.getCurrentServerAddr()});
|
||||
throw ioe;
|
||||
}
|
||||
do {
|
||||
try {
|
||||
List<String> newHeaders = getSpasHeaders(paramValues);
|
||||
if (headers != null) {
|
||||
newHeaders.addAll(headers);
|
||||
}
|
||||
HttpResult result = HttpSimpleClient.httpGet(
|
||||
getUrl(serverListMgr.getCurrentServerAddr(), path, isSSL), newHeaders, paramValues, encoding,
|
||||
readTimeoutMs, isSSL);
|
||||
if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR
|
||||
|| result.code == HttpURLConnection.HTTP_BAD_GATEWAY
|
||||
|| result.code == HttpURLConnection.HTTP_UNAVAILABLE) {
|
||||
log.error("NACOS ConnectException", "currentServerAddr:{}. httpCode:",
|
||||
new Object[] {serverListMgr.getCurrentServerAddr(), result.code});
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
} catch (ConnectException ce) {
|
||||
log.error("NACOS ConnectException", "currentServerAddr:{}",
|
||||
new Object[] {serverListMgr.getCurrentServerAddr()});
|
||||
serverListMgr.refreshCurrentServerAddr();
|
||||
} catch (SocketTimeoutException stoe) {
|
||||
log.error("NACOS SocketTimeoutException", "currentServerAddr:{}",
|
||||
new Object[] {serverListMgr.getCurrentServerAddr()});
|
||||
serverListMgr.refreshCurrentServerAddr();
|
||||
} catch (IOException ioe) {
|
||||
log.error("NACOS IOException", "currentServerAddr:{}",
|
||||
new Object[] {serverListMgr.getCurrentServerAddr()});
|
||||
throw ioe;
|
||||
}
|
||||
} while (System.currentTimeMillis() <= endTime);
|
||||
|
||||
} while (System.currentTimeMillis() <= endTime);
|
||||
log.error("NACOS-0002",
|
||||
LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0002", "环境问题", "no available server"));
|
||||
throw new ConnectException("no available server");
|
||||
}
|
||||
|
||||
log.error("NACOS-0002",
|
||||
LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0002", "环境问题", "no available server"));
|
||||
throw new ConnectException("no available server");
|
||||
}
|
||||
|
||||
public HttpResult httpDelete(String path, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs) throws IOException {
|
||||
final long endTime = System.currentTimeMillis() + readTimeoutMs;
|
||||
boolean isSSL = false;
|
||||
do {
|
||||
try {
|
||||
List<String> newHeaders = getSpasHeaders(paramValues);
|
||||
if (headers != null) {
|
||||
newHeaders.addAll(headers);
|
||||
}
|
||||
HttpResult result = HttpSimpleClient.httpDelete(
|
||||
getUrl(serverListMgr.getCurrentServerAddr(), path, isSSL), newHeaders, paramValues, encoding,
|
||||
readTimeoutMs, isSSL);
|
||||
if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR
|
||||
|| result.code == HttpURLConnection.HTTP_BAD_GATEWAY
|
||||
|| result.code == HttpURLConnection.HTTP_UNAVAILABLE) {
|
||||
log.error("NACOS ConnectException", "currentServerAddr:{}. httpCode:",
|
||||
new Object[] { serverListMgr.getCurrentServerAddr(), result.code });
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
} catch (ConnectException ce) {
|
||||
log.error("NACOS ConnectException", "currentServerAddr:{}",
|
||||
new Object[] { serverListMgr.getCurrentServerAddr()});
|
||||
serverListMgr.refreshCurrentServerAddr();
|
||||
} catch (SocketTimeoutException stoe) {
|
||||
log.error("NACOS SocketTimeoutException", "currentServerAddr:{}",
|
||||
new Object[] { serverListMgr.getCurrentServerAddr()});
|
||||
serverListMgr.refreshCurrentServerAddr();
|
||||
} catch (IOException ioe) {
|
||||
log.error("NACOS IOException", "currentServerAddr:{}",
|
||||
new Object[] { serverListMgr.getCurrentServerAddr()});
|
||||
throw ioe;
|
||||
}
|
||||
|
||||
} while (System.currentTimeMillis() <= endTime);
|
||||
|
||||
log.error("NACOS-0002",
|
||||
LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0002", "环境问题", "no available server"));
|
||||
throw new ConnectException("no available server");
|
||||
}
|
||||
public HttpResult httpPost(String path, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs) throws IOException {
|
||||
final long endTime = System.currentTimeMillis() + readTimeoutMs;
|
||||
boolean isSSL = false;
|
||||
do {
|
||||
try {
|
||||
List<String> newHeaders = getSpasHeaders(paramValues);
|
||||
if (headers != null) {
|
||||
newHeaders.addAll(headers);
|
||||
}
|
||||
HttpResult result = HttpSimpleClient.httpPost(
|
||||
getUrl(serverListMgr.getCurrentServerAddr(), path, isSSL), newHeaders, paramValues, encoding,
|
||||
readTimeoutMs, isSSL);
|
||||
if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR
|
||||
|| result.code == HttpURLConnection.HTTP_BAD_GATEWAY
|
||||
|| result.code == HttpURLConnection.HTTP_UNAVAILABLE) {
|
||||
log.error("NACOS ConnectException", "currentServerAddr:{}. httpCode:",
|
||||
new Object[] {serverListMgr.getCurrentServerAddr(), result.code});
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
} catch (ConnectException ce) {
|
||||
log.error("NACOS ConnectException", "currentServerAddr:{}",
|
||||
new Object[] {serverListMgr.getCurrentServerAddr()});
|
||||
serverListMgr.refreshCurrentServerAddr();
|
||||
} catch (SocketTimeoutException stoe) {
|
||||
log.error("NACOS SocketTimeoutException", "currentServerAddr:{}",
|
||||
new Object[] {serverListMgr.getCurrentServerAddr()});
|
||||
serverListMgr.refreshCurrentServerAddr();
|
||||
} catch (IOException ioe) {
|
||||
log.error("NACOS IOException", "currentServerAddr:{}",
|
||||
new Object[] {serverListMgr.getCurrentServerAddr()});
|
||||
throw ioe;
|
||||
}
|
||||
|
||||
private String getUrl(String serverAddr, String relativePath, boolean isSSL) {
|
||||
String httpPrefix = "http://";
|
||||
if (isSSL) {
|
||||
httpPrefix = "https://";
|
||||
}
|
||||
return httpPrefix + serverAddr + "/" + serverListMgr.getContentPath() + relativePath;
|
||||
}
|
||||
} while (System.currentTimeMillis() <= endTime);
|
||||
|
||||
public static String getAppname() {
|
||||
return ParamUtil.getAppName();
|
||||
}
|
||||
log.error("NACOS-0002",
|
||||
LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0002", "环境问题", "no available server"));
|
||||
throw new ConnectException("no available server");
|
||||
}
|
||||
|
||||
public ServerHttpAgent(ServerListManager mgr) {
|
||||
serverListMgr = mgr;
|
||||
}
|
||||
|
||||
public ServerHttpAgent(ServerListManager mgr, Properties properties) {
|
||||
serverListMgr = mgr;
|
||||
String ak = properties.getProperty(PropertyKeyConst.ACCESS_KEY);
|
||||
if (StringUtils.isBlank(ak)) {
|
||||
accessKey = SpasAdapter.getAk();
|
||||
} else {
|
||||
accessKey = ak;
|
||||
}
|
||||
public HttpResult httpDelete(String path, List<String> headers, List<String> paramValues, String encoding,
|
||||
long readTimeoutMs) throws IOException {
|
||||
final long endTime = System.currentTimeMillis() + readTimeoutMs;
|
||||
boolean isSSL = false;
|
||||
do {
|
||||
try {
|
||||
List<String> newHeaders = getSpasHeaders(paramValues);
|
||||
if (headers != null) {
|
||||
newHeaders.addAll(headers);
|
||||
}
|
||||
HttpResult result = HttpSimpleClient.httpDelete(
|
||||
getUrl(serverListMgr.getCurrentServerAddr(), path, isSSL), newHeaders, paramValues, encoding,
|
||||
readTimeoutMs, isSSL);
|
||||
if (result.code == HttpURLConnection.HTTP_INTERNAL_ERROR
|
||||
|| result.code == HttpURLConnection.HTTP_BAD_GATEWAY
|
||||
|| result.code == HttpURLConnection.HTTP_UNAVAILABLE) {
|
||||
log.error("NACOS ConnectException", "currentServerAddr:{}. httpCode:",
|
||||
new Object[] {serverListMgr.getCurrentServerAddr(), result.code});
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
} catch (ConnectException ce) {
|
||||
log.error("NACOS ConnectException", "currentServerAddr:{}",
|
||||
new Object[] {serverListMgr.getCurrentServerAddr()});
|
||||
serverListMgr.refreshCurrentServerAddr();
|
||||
} catch (SocketTimeoutException stoe) {
|
||||
log.error("NACOS SocketTimeoutException", "currentServerAddr:{}",
|
||||
new Object[] {serverListMgr.getCurrentServerAddr()});
|
||||
serverListMgr.refreshCurrentServerAddr();
|
||||
} catch (IOException ioe) {
|
||||
log.error("NACOS IOException", "currentServerAddr:{}",
|
||||
new Object[] {serverListMgr.getCurrentServerAddr()});
|
||||
throw ioe;
|
||||
}
|
||||
|
||||
String sk = properties.getProperty(PropertyKeyConst.SECRET_KEY);
|
||||
if (StringUtils.isBlank(sk)) {
|
||||
secretKey = SpasAdapter.getSk();
|
||||
} else {
|
||||
secretKey = sk;
|
||||
}
|
||||
}
|
||||
|
||||
public ServerHttpAgent(Properties properties) throws NacosException {
|
||||
String encodeTmp = properties.getProperty(PropertyKeyConst.ENCODE);
|
||||
if (StringUtils.isBlank(encodeTmp)) {
|
||||
encode = Constants.ENCODE;
|
||||
} else {
|
||||
encode = encodeTmp.trim();
|
||||
}
|
||||
serverListMgr = new ServerListManager(properties);
|
||||
String ak = properties.getProperty(PropertyKeyConst.ACCESS_KEY);
|
||||
if (StringUtils.isBlank(ak)) {
|
||||
accessKey = SpasAdapter.getAk();
|
||||
} else {
|
||||
accessKey = ak;
|
||||
}
|
||||
|
||||
String sk = properties.getProperty(PropertyKeyConst.SECRET_KEY);
|
||||
if (StringUtils.isBlank(sk)) {
|
||||
secretKey = SpasAdapter.getSk();
|
||||
} else {
|
||||
secretKey = sk;
|
||||
}
|
||||
}
|
||||
} while (System.currentTimeMillis() <= endTime);
|
||||
|
||||
public synchronized void start() throws NacosException {
|
||||
serverListMgr.start();
|
||||
}
|
||||
|
||||
private List<String> getSpasHeaders(List<String> paramValues) throws IOException {
|
||||
List<String> newHeaders = new ArrayList<String>();
|
||||
// STS 临时凭证鉴权的优先级高于 AK/SK 鉴权
|
||||
if (STSConfig.getInstance().isSTSOn()) {
|
||||
STSCredential sTSCredential = getSTSCredential();
|
||||
accessKey = sTSCredential.accessKeyId;
|
||||
secretKey = sTSCredential.accessKeySecret;
|
||||
newHeaders.add("Spas-SecurityToken");
|
||||
newHeaders.add(sTSCredential.securityToken);
|
||||
}
|
||||
log.error("NACOS-0002",
|
||||
LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0002", "环境问题", "no available server"));
|
||||
throw new ConnectException("no available server");
|
||||
}
|
||||
|
||||
if (StringUtils.isNotEmpty(accessKey) && StringUtils.isNotEmpty(secretKey)) {
|
||||
newHeaders.add("Spas-AccessKey");
|
||||
newHeaders.add(accessKey);
|
||||
List<String> signHeaders = SpasAdapter.getSignHeaders(paramValues, secretKey);
|
||||
if (signHeaders != null) {
|
||||
newHeaders.addAll(signHeaders);
|
||||
}
|
||||
}
|
||||
return newHeaders;
|
||||
}
|
||||
private String getUrl(String serverAddr, String relativePath, boolean isSSL) {
|
||||
String httpPrefix = "http://";
|
||||
if (isSSL) {
|
||||
httpPrefix = "https://";
|
||||
}
|
||||
return httpPrefix + serverAddr + "/" + serverListMgr.getContentPath() + relativePath;
|
||||
}
|
||||
|
||||
private STSCredential getSTSCredential() throws IOException {
|
||||
boolean cacheSecurityCredentials = STSConfig.getInstance().isCacheSecurityCredentials();
|
||||
if (cacheSecurityCredentials && sTSCredential != null) {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
long expirationTime = sTSCredential.expiration.getTime();
|
||||
int timeToRefreshInMillisecond = STSConfig.getInstance().getTimeToRefreshInMillisecond();
|
||||
if (expirationTime - currentTime > timeToRefreshInMillisecond) {
|
||||
return sTSCredential;
|
||||
}
|
||||
}
|
||||
String stsResponse = getSTSResponse();
|
||||
STSCredential stsCredentialTmp = (STSCredential)JSONUtils.deserializeObject(stsResponse,
|
||||
new TypeReference<STSCredential>() {});
|
||||
sTSCredential = stsCredentialTmp;
|
||||
log.info("getSTSCredential", "code:{}, accessKeyId:{}, lastUpdated:{}, expiration:{}", sTSCredential.getCode(),
|
||||
sTSCredential.getAccessKeyId(), sTSCredential.getLastUpdated(), sTSCredential.getExpiration());
|
||||
return sTSCredential;
|
||||
}
|
||||
public static String getAppname() {
|
||||
return ParamUtil.getAppName();
|
||||
}
|
||||
|
||||
private static String getSTSResponse() throws IOException {
|
||||
String securityCredentials = STSConfig.getInstance().getSecurityCredentials();
|
||||
if (securityCredentials != null) {
|
||||
return securityCredentials;
|
||||
}
|
||||
String securityCredentialsUrl = STSConfig.getInstance().getSecurityCredentialsUrl();
|
||||
HttpURLConnection conn = null;
|
||||
int respCode;
|
||||
String response;
|
||||
try {
|
||||
conn = (HttpURLConnection)new URL(securityCredentialsUrl).openConnection();
|
||||
conn.setRequestMethod("GET");
|
||||
conn.setConnectTimeout(ParamUtil.getConnectTimeout() > 100 ? ParamUtil.getConnectTimeout() : 100);
|
||||
conn.setReadTimeout(1000);
|
||||
conn.connect();
|
||||
respCode = conn.getResponseCode();
|
||||
if (HttpURLConnection.HTTP_OK == respCode) {
|
||||
response = IOUtils.toString(conn.getInputStream(), Constants.ENCODE);
|
||||
} else {
|
||||
response = IOUtils.toString(conn.getErrorStream(), Constants.ENCODE);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("500", "can not get security credentials", e);
|
||||
throw e;
|
||||
} finally {
|
||||
if (null != conn) {
|
||||
conn.disconnect();
|
||||
}
|
||||
}
|
||||
if (HttpURLConnection.HTTP_OK == respCode) {
|
||||
return response;
|
||||
}
|
||||
log.error(respCode + "", "can not get security credentials, securityCredentialsUrl:{}, response:{}",
|
||||
new Object[] {securityCredentialsUrl, response});
|
||||
throw new IOException("can not get security credentials, responseCode: " + respCode + ", response: " + response);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return serverListMgr.getName();
|
||||
}
|
||||
public ServerHttpAgent(ServerListManager mgr) {
|
||||
serverListMgr = mgr;
|
||||
}
|
||||
|
||||
public String getNamespace() {
|
||||
return serverListMgr.getNamespace();
|
||||
}
|
||||
public String getTenant() {
|
||||
return serverListMgr.getTenant();
|
||||
}
|
||||
public ServerHttpAgent(ServerListManager mgr, Properties properties) {
|
||||
serverListMgr = mgr;
|
||||
String ak = properties.getProperty(PropertyKeyConst.ACCESS_KEY);
|
||||
if (StringUtils.isBlank(ak)) {
|
||||
accessKey = SpasAdapter.getAk();
|
||||
} else {
|
||||
accessKey = ak;
|
||||
}
|
||||
|
||||
public String getEncode() {
|
||||
return encode;
|
||||
}
|
||||
String sk = properties.getProperty(PropertyKeyConst.SECRET_KEY);
|
||||
if (StringUtils.isBlank(sk)) {
|
||||
secretKey = SpasAdapter.getSk();
|
||||
} else {
|
||||
secretKey = sk;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
|
||||
private static class STSCredential {
|
||||
@JsonProperty(value = "AccessKeyId")
|
||||
private String accessKeyId;
|
||||
@JsonProperty(value = "AccessKeySecret")
|
||||
private String accessKeySecret;
|
||||
@JsonProperty(value = "Expiration")
|
||||
private Date expiration;
|
||||
@JsonProperty(value = "SecurityToken")
|
||||
private String securityToken;
|
||||
@JsonProperty(value = "LastUpdated")
|
||||
private Date lastUpdated;
|
||||
@JsonProperty(value = "Code")
|
||||
private String code;
|
||||
public ServerHttpAgent(Properties properties) throws NacosException {
|
||||
String encodeTmp = properties.getProperty(PropertyKeyConst.ENCODE);
|
||||
if (StringUtils.isBlank(encodeTmp)) {
|
||||
encode = Constants.ENCODE;
|
||||
} else {
|
||||
encode = encodeTmp.trim();
|
||||
}
|
||||
serverListMgr = new ServerListManager(properties);
|
||||
String ak = properties.getProperty(PropertyKeyConst.ACCESS_KEY);
|
||||
if (StringUtils.isBlank(ak)) {
|
||||
accessKey = SpasAdapter.getAk();
|
||||
} else {
|
||||
accessKey = ak;
|
||||
}
|
||||
|
||||
public String getAccessKeyId() {
|
||||
return accessKeyId;
|
||||
}
|
||||
String sk = properties.getProperty(PropertyKeyConst.SECRET_KEY);
|
||||
if (StringUtils.isBlank(sk)) {
|
||||
secretKey = SpasAdapter.getSk();
|
||||
} else {
|
||||
secretKey = sk;
|
||||
}
|
||||
}
|
||||
|
||||
public Date getExpiration() {
|
||||
return expiration;
|
||||
}
|
||||
public synchronized void start() throws NacosException {
|
||||
serverListMgr.start();
|
||||
}
|
||||
|
||||
public Date getLastUpdated() {
|
||||
return lastUpdated;
|
||||
}
|
||||
private List<String> getSpasHeaders(List<String> paramValues) throws IOException {
|
||||
List<String> newHeaders = new ArrayList<String>();
|
||||
// STS 临时凭证鉴权的优先级高于 AK/SK 鉴权
|
||||
if (STSConfig.getInstance().isSTSOn()) {
|
||||
STSCredential sTSCredential = getSTSCredential();
|
||||
accessKey = sTSCredential.accessKeyId;
|
||||
secretKey = sTSCredential.accessKeySecret;
|
||||
newHeaders.add("Spas-SecurityToken");
|
||||
newHeaders.add(sTSCredential.securityToken);
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
if (StringUtils.isNotEmpty(accessKey) && StringUtils.isNotEmpty(secretKey)) {
|
||||
newHeaders.add("Spas-AccessKey");
|
||||
newHeaders.add(accessKey);
|
||||
List<String> signHeaders = SpasAdapter.getSignHeaders(paramValues, secretKey);
|
||||
if (signHeaders != null) {
|
||||
newHeaders.addAll(signHeaders);
|
||||
}
|
||||
}
|
||||
return newHeaders;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "STSCredential{" +
|
||||
"accessKeyId='" + accessKeyId + '\'' +
|
||||
", accessKeySecret='" + accessKeySecret + '\'' +
|
||||
", expiration=" + expiration +
|
||||
", securityToken='" + securityToken + '\'' +
|
||||
", lastUpdated=" + lastUpdated +
|
||||
", code='" + code + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
private String accessKey;
|
||||
private String secretKey;
|
||||
private String encode;
|
||||
private volatile STSCredential sTSCredential;
|
||||
final ServerListManager serverListMgr;
|
||||
private STSCredential getSTSCredential() throws IOException {
|
||||
boolean cacheSecurityCredentials = STSConfig.getInstance().isCacheSecurityCredentials();
|
||||
if (cacheSecurityCredentials && sTSCredential != null) {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
long expirationTime = sTSCredential.expiration.getTime();
|
||||
int timeToRefreshInMillisecond = STSConfig.getInstance().getTimeToRefreshInMillisecond();
|
||||
if (expirationTime - currentTime > timeToRefreshInMillisecond) {
|
||||
return sTSCredential;
|
||||
}
|
||||
}
|
||||
String stsResponse = getSTSResponse();
|
||||
STSCredential stsCredentialTmp = (STSCredential)JSONUtils.deserializeObject(stsResponse,
|
||||
new TypeReference<STSCredential>() {});
|
||||
sTSCredential = stsCredentialTmp;
|
||||
log.info("getSTSCredential", "code:{}, accessKeyId:{}, lastUpdated:{}, expiration:{}", sTSCredential.getCode(),
|
||||
sTSCredential.getAccessKeyId(), sTSCredential.getLastUpdated(), sTSCredential.getExpiration());
|
||||
return sTSCredential;
|
||||
}
|
||||
|
||||
private static String getSTSResponse() throws IOException {
|
||||
String securityCredentials = STSConfig.getInstance().getSecurityCredentials();
|
||||
if (securityCredentials != null) {
|
||||
return securityCredentials;
|
||||
}
|
||||
String securityCredentialsUrl = STSConfig.getInstance().getSecurityCredentialsUrl();
|
||||
HttpURLConnection conn = null;
|
||||
int respCode;
|
||||
String response;
|
||||
try {
|
||||
conn = (HttpURLConnection)new URL(securityCredentialsUrl).openConnection();
|
||||
conn.setRequestMethod("GET");
|
||||
conn.setConnectTimeout(ParamUtil.getConnectTimeout() > 100 ? ParamUtil.getConnectTimeout() : 100);
|
||||
conn.setReadTimeout(1000);
|
||||
conn.connect();
|
||||
respCode = conn.getResponseCode();
|
||||
if (HttpURLConnection.HTTP_OK == respCode) {
|
||||
response = IOUtils.toString(conn.getInputStream(), Constants.ENCODE);
|
||||
} else {
|
||||
response = IOUtils.toString(conn.getErrorStream(), Constants.ENCODE);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("500", "can not get security credentials", e);
|
||||
throw e;
|
||||
} finally {
|
||||
if (null != conn) {
|
||||
conn.disconnect();
|
||||
}
|
||||
}
|
||||
if (HttpURLConnection.HTTP_OK == respCode) {
|
||||
return response;
|
||||
}
|
||||
log.error(respCode + "", "can not get security credentials, securityCredentialsUrl:{}, response:{}",
|
||||
new Object[] {securityCredentialsUrl, response});
|
||||
throw new IOException(
|
||||
"can not get security credentials, responseCode: " + respCode + ", response: " + response);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return serverListMgr.getName();
|
||||
}
|
||||
|
||||
public String getNamespace() {
|
||||
return serverListMgr.getNamespace();
|
||||
}
|
||||
|
||||
public String getTenant() {
|
||||
return serverListMgr.getTenant();
|
||||
}
|
||||
|
||||
public String getEncode() {
|
||||
return encode;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
|
||||
private static class STSCredential {
|
||||
@JsonProperty(value = "AccessKeyId")
|
||||
private String accessKeyId;
|
||||
@JsonProperty(value = "AccessKeySecret")
|
||||
private String accessKeySecret;
|
||||
@JsonProperty(value = "Expiration")
|
||||
private Date expiration;
|
||||
@JsonProperty(value = "SecurityToken")
|
||||
private String securityToken;
|
||||
@JsonProperty(value = "LastUpdated")
|
||||
private Date lastUpdated;
|
||||
@JsonProperty(value = "Code")
|
||||
private String code;
|
||||
|
||||
public String getAccessKeyId() {
|
||||
return accessKeyId;
|
||||
}
|
||||
|
||||
public Date getExpiration() {
|
||||
return expiration;
|
||||
}
|
||||
|
||||
public Date getLastUpdated() {
|
||||
return lastUpdated;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "STSCredential{" +
|
||||
"accessKeyId='" + accessKeyId + '\'' +
|
||||
", accessKeySecret='" + accessKeySecret + '\'' +
|
||||
", expiration=" + expiration +
|
||||
", securityToken='" + securityToken + '\'' +
|
||||
", lastUpdated=" + lastUpdated +
|
||||
", code='" + code + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
private String accessKey;
|
||||
private String secretKey;
|
||||
private String encode;
|
||||
private volatile STSCredential sTSCredential;
|
||||
final ServerListManager serverListMgr;
|
||||
|
||||
}
|
||||
|
@ -40,212 +40,213 @@ import com.alibaba.nacos.client.utils.StringUtils;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
|
||||
/**
|
||||
* Serverlist Manager
|
||||
*
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class ServerListManager {
|
||||
|
||||
final static public Logger log = LogUtils.logger(ServerListManager.class);
|
||||
public ServerListManager() {
|
||||
isFixed = false;
|
||||
isStarted = false;
|
||||
name = DEFAULT_NAME;
|
||||
}
|
||||
|
||||
public ServerListManager(List<String> fixed) {
|
||||
this(fixed, null);
|
||||
}
|
||||
|
||||
public ServerListManager(List<String> fixed, String namespace) {
|
||||
isFixed = true;
|
||||
isStarted = true;
|
||||
List<String> serverAddrs = new ArrayList<String>();
|
||||
for (String serverAddr : fixed) {
|
||||
String[] serverAddrArr = serverAddr.split(":");
|
||||
if (serverAddrArr.length == 1) {
|
||||
serverAddrs.add(serverAddrArr[0] + ":" + ParamUtil.getDefaultServerPort());
|
||||
} else {
|
||||
serverAddrs.add(serverAddr);
|
||||
}
|
||||
}
|
||||
serverUrls = new ArrayList<String>(serverAddrs);
|
||||
if (StringUtils.isBlank(namespace)) {
|
||||
name = FIXED_NAME + "-" + getFixedNameSuffix(serverAddrs.toArray(new String[serverAddrs.size()]));
|
||||
} else {
|
||||
this.namespace = namespace;
|
||||
name = FIXED_NAME + "-" + getFixedNameSuffix(serverAddrs.toArray(new String[serverAddrs.size()])) + "-"
|
||||
+ namespace;
|
||||
}
|
||||
}
|
||||
final static public Logger log = LogUtils.logger(ServerListManager.class);
|
||||
|
||||
public ServerListManager(String host, int port) {
|
||||
isFixed = false;
|
||||
isStarted = false;
|
||||
name = CUSTOM_NAME + "-" + host + "-" + port;
|
||||
addressServerUrl = String.format("http://%s:%d/%s/%s", host, port, contentPath, serverListName);
|
||||
}
|
||||
public ServerListManager() {
|
||||
isFixed = false;
|
||||
isStarted = false;
|
||||
name = DEFAULT_NAME;
|
||||
}
|
||||
|
||||
public ServerListManager(String endpoint) throws NacosException {
|
||||
this(endpoint, null);
|
||||
}
|
||||
public ServerListManager(List<String> fixed) {
|
||||
this(fixed, null);
|
||||
}
|
||||
|
||||
public ServerListManager(List<String> fixed, String namespace) {
|
||||
isFixed = true;
|
||||
isStarted = true;
|
||||
List<String> serverAddrs = new ArrayList<String>();
|
||||
for (String serverAddr : fixed) {
|
||||
String[] serverAddrArr = serverAddr.split(":");
|
||||
if (serverAddrArr.length == 1) {
|
||||
serverAddrs.add(serverAddrArr[0] + ":" + ParamUtil.getDefaultServerPort());
|
||||
} else {
|
||||
serverAddrs.add(serverAddr);
|
||||
}
|
||||
}
|
||||
serverUrls = new ArrayList<String>(serverAddrs);
|
||||
if (StringUtils.isBlank(namespace)) {
|
||||
name = FIXED_NAME + "-" + getFixedNameSuffix(serverAddrs.toArray(new String[serverAddrs.size()]));
|
||||
} else {
|
||||
this.namespace = namespace;
|
||||
name = FIXED_NAME + "-" + getFixedNameSuffix(serverAddrs.toArray(new String[serverAddrs.size()])) + "-"
|
||||
+ namespace;
|
||||
}
|
||||
}
|
||||
|
||||
public ServerListManager(String host, int port) {
|
||||
isFixed = false;
|
||||
isStarted = false;
|
||||
name = CUSTOM_NAME + "-" + host + "-" + port;
|
||||
addressServerUrl = String.format("http://%s:%d/%s/%s", host, port, contentPath, serverListName);
|
||||
}
|
||||
|
||||
public ServerListManager(String endpoint) throws NacosException {
|
||||
this(endpoint, null);
|
||||
}
|
||||
|
||||
public ServerListManager(String endpoint, String namespace) throws NacosException {
|
||||
isFixed = false;
|
||||
isStarted = false;
|
||||
if (StringUtils.isBlank(endpoint)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "endpoint is blank");
|
||||
}
|
||||
if (StringUtils.isBlank(namespace)) {
|
||||
name = endpoint;
|
||||
addressServerUrl = String.format("http://%s:%d/%s/%s", endpoint, endpointPort, contentPath,
|
||||
serverListName);
|
||||
} else {
|
||||
if (StringUtils.isBlank(endpoint)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "endpoint is blank");
|
||||
}
|
||||
name = endpoint + "-" + namespace;
|
||||
this.namespace = namespace;
|
||||
this.tenant = namespace;
|
||||
addressServerUrl = String.format("http://%s:%d/%s/%s?namespace=%s", endpoint, endpointPort, contentPath,
|
||||
serverListName, namespace);
|
||||
}
|
||||
}
|
||||
|
||||
public ServerListManager(Properties properties) throws NacosException {
|
||||
isStarted = false;
|
||||
String serverAddrsStr = properties.getProperty(PropertyKeyConst.SERVER_ADDR);
|
||||
String namespace = properties.getProperty(PropertyKeyConst.NAMESPACE);
|
||||
initParam(properties);
|
||||
if (StringUtils.isNotEmpty(serverAddrsStr)) {
|
||||
isFixed = true;
|
||||
List<String> serverAddrs = new ArrayList<String>();
|
||||
String[] serverAddrsArr = serverAddrsStr.split(",");
|
||||
for (String serverAddr : serverAddrsArr) {
|
||||
String[] serverAddrArr = serverAddr.split(":");
|
||||
if (serverAddrArr.length == 1) {
|
||||
serverAddrs.add(serverAddrArr[0] + ":" + ParamUtil.getDefaultServerPort());
|
||||
} else {
|
||||
serverAddrs.add(serverAddr);
|
||||
}
|
||||
}
|
||||
serverUrls = serverAddrs;
|
||||
if (StringUtils.isBlank(namespace)) {
|
||||
name = FIXED_NAME + "-" + getFixedNameSuffix(serverUrls.toArray(new String[serverUrls.size()]));
|
||||
} else {
|
||||
this.namespace = namespace;
|
||||
this.tenant = namespace;
|
||||
name = FIXED_NAME + "-" + getFixedNameSuffix(serverUrls.toArray(new String[serverUrls.size()])) + "-"
|
||||
+ namespace;
|
||||
}
|
||||
} else {
|
||||
if (StringUtils.isBlank(endpoint)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "endpoint is blank");
|
||||
}
|
||||
isFixed = false;
|
||||
if (StringUtils.isBlank(namespace)) {
|
||||
name = endpoint;
|
||||
addressServerUrl = String.format("http://%s:%d/%s/%s", endpoint, endpointPort, contentPath,
|
||||
serverListName);
|
||||
} else {
|
||||
this.namespace = namespace;
|
||||
this.tenant = namespace;
|
||||
name = endpoint + "-" + namespace;
|
||||
addressServerUrl = String.format("http://%s:%d/%s/%s?namespace=%s", endpoint, endpointPort,
|
||||
contentPath, serverListName, namespace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initParam(Properties properties) {
|
||||
String endpointTmp = properties.getProperty(PropertyKeyConst.ENDPOINT);
|
||||
if (!StringUtils.isBlank(endpointTmp)) {
|
||||
endpoint = endpointTmp;
|
||||
}
|
||||
String contentPathTmp = properties.getProperty(PropertyKeyConst.CONTEXT_PATH);
|
||||
if (!StringUtils.isBlank(contentPathTmp)) {
|
||||
contentPath = contentPathTmp;
|
||||
}
|
||||
String serverListNameTmp = properties.getProperty(PropertyKeyConst.CLUSTER_NAME);
|
||||
if (!StringUtils.isBlank(serverListNameTmp)) {
|
||||
serverListName = serverListNameTmp;
|
||||
}
|
||||
}
|
||||
|
||||
public ServerListManager(String endpoint, String namespace) throws NacosException {
|
||||
isFixed = false;
|
||||
isStarted = false;
|
||||
if (StringUtils.isBlank(endpoint)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "endpoint is blank");
|
||||
}
|
||||
if (StringUtils.isBlank(namespace)) {
|
||||
name = endpoint;
|
||||
addressServerUrl = String.format("http://%s:%d/%s/%s", endpoint, endpointPort, contentPath,
|
||||
serverListName);
|
||||
} else {
|
||||
if (StringUtils.isBlank(endpoint)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "endpoint is blank");
|
||||
}
|
||||
name = endpoint + "-" + namespace;
|
||||
this.namespace = namespace;
|
||||
this.tenant = namespace;
|
||||
addressServerUrl = String.format("http://%s:%d/%s/%s?namespace=%s", endpoint, endpointPort, contentPath,
|
||||
serverListName, namespace);
|
||||
}
|
||||
}
|
||||
|
||||
public ServerListManager(Properties properties) throws NacosException {
|
||||
isStarted = false;
|
||||
String serverAddrsStr = properties.getProperty(PropertyKeyConst.SERVER_ADDR);
|
||||
String namespace = properties.getProperty(PropertyKeyConst.NAMESPACE);
|
||||
initParam(properties);
|
||||
if (StringUtils.isNotEmpty(serverAddrsStr)) {
|
||||
isFixed = true;
|
||||
List<String> serverAddrs = new ArrayList<String>();
|
||||
String[] serverAddrsArr = serverAddrsStr.split(",");
|
||||
for (String serverAddr : serverAddrsArr) {
|
||||
String[] serverAddrArr = serverAddr.split(":");
|
||||
if (serverAddrArr.length == 1) {
|
||||
serverAddrs.add(serverAddrArr[0] + ":" + ParamUtil.getDefaultServerPort());
|
||||
} else {
|
||||
serverAddrs.add(serverAddr);
|
||||
}
|
||||
}
|
||||
serverUrls = serverAddrs;
|
||||
if (StringUtils.isBlank(namespace)) {
|
||||
name = FIXED_NAME + "-" + getFixedNameSuffix(serverUrls.toArray(new String[serverUrls.size()]));
|
||||
} else {
|
||||
this.namespace = namespace;
|
||||
this.tenant = namespace;
|
||||
name = FIXED_NAME + "-" + getFixedNameSuffix(serverUrls.toArray(new String[serverUrls.size()])) + "-"
|
||||
+ namespace;
|
||||
}
|
||||
} else {
|
||||
if (StringUtils.isBlank(endpoint)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "endpoint is blank");
|
||||
}
|
||||
isFixed = false;
|
||||
if (StringUtils.isBlank(namespace)) {
|
||||
name = endpoint;
|
||||
addressServerUrl = String.format("http://%s:%d/%s/%s", endpoint, endpointPort, contentPath,
|
||||
serverListName);
|
||||
} else {
|
||||
this.namespace = namespace;
|
||||
this.tenant = namespace;
|
||||
name = endpoint + "-" + namespace;
|
||||
addressServerUrl = String.format("http://%s:%d/%s/%s?namespace=%s", endpoint, endpointPort,
|
||||
contentPath, serverListName, namespace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initParam(Properties properties) {
|
||||
String endpointTmp = properties.getProperty(PropertyKeyConst.ENDPOINT);
|
||||
if (!StringUtils.isBlank(endpointTmp)) {
|
||||
endpoint = endpointTmp;
|
||||
}
|
||||
String contentPathTmp = properties.getProperty(PropertyKeyConst.CONTEXT_PATH);
|
||||
if (!StringUtils.isBlank(contentPathTmp)) {
|
||||
contentPath = contentPathTmp;
|
||||
}
|
||||
String serverListNameTmp = properties.getProperty(PropertyKeyConst.CLUSTER_NAME);
|
||||
if (!StringUtils.isBlank(serverListNameTmp)) {
|
||||
serverListName = serverListNameTmp;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void start() throws NacosException {
|
||||
|
||||
|
||||
if (isStarted || isFixed) {
|
||||
return;
|
||||
}
|
||||
|
||||
GetServerListTask getServersTask = new GetServerListTask(addressServerUrl);
|
||||
for (int i = 0; i < initServerlistRetryTimes && serverUrls.isEmpty(); ++i) {
|
||||
getServersTask.run();
|
||||
try {
|
||||
this.wait((i + 1) * 100L);
|
||||
} catch (Exception e) {
|
||||
log.warn("get serverlist fail,url: " + addressServerUrl);
|
||||
}
|
||||
}
|
||||
GetServerListTask getServersTask = new GetServerListTask(addressServerUrl);
|
||||
for (int i = 0; i < initServerlistRetryTimes && serverUrls.isEmpty(); ++i) {
|
||||
getServersTask.run();
|
||||
try {
|
||||
this.wait((i + 1) * 100L);
|
||||
} catch (Exception e) {
|
||||
log.warn("get serverlist fail,url: " + addressServerUrl);
|
||||
}
|
||||
}
|
||||
|
||||
if (serverUrls.isEmpty()) {
|
||||
log.error("NACOS-0008", LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0008", "环境问题",
|
||||
"fail to get NACOS-server serverlist! env:" + name + ", not connnect url:" + addressServerUrl));
|
||||
log.error(name, "NACOS-XXXX", "[init-serverlist] fail to get NACOS-server serverlist!");
|
||||
throw new NacosException(NacosException.SERVER_ERROR,
|
||||
"fail to get NACOS-server serverlist! env:" + name + ", not connnect url:" + addressServerUrl);
|
||||
}
|
||||
if (serverUrls.isEmpty()) {
|
||||
log.error("NACOS-0008", LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0008", "环境问题",
|
||||
"fail to get NACOS-server serverlist! env:" + name + ", not connnect url:" + addressServerUrl));
|
||||
log.error(name, "NACOS-XXXX", "[init-serverlist] fail to get NACOS-server serverlist!");
|
||||
throw new NacosException(NacosException.SERVER_ERROR,
|
||||
"fail to get NACOS-server serverlist! env:" + name + ", not connnect url:" + addressServerUrl);
|
||||
}
|
||||
|
||||
TimerService.scheduleWithFixedDelay(getServersTask, 0L, 30L, TimeUnit.SECONDS);
|
||||
isStarted = true;
|
||||
}
|
||||
|
||||
|
||||
Iterator<String> iterator() {
|
||||
if (serverUrls.isEmpty()) {
|
||||
log.error(name, "NACOS-XXXX", "[iterator-serverlist] No server address defined!");
|
||||
}
|
||||
return new ServerAddressIterator(serverUrls);
|
||||
}
|
||||
|
||||
|
||||
class GetServerListTask implements Runnable {
|
||||
final String url;
|
||||
|
||||
|
||||
GetServerListTask(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
/**
|
||||
* get serverlist from nameserver
|
||||
*/
|
||||
public void run() {
|
||||
/**
|
||||
* get serverlist from nameserver
|
||||
*/
|
||||
try {
|
||||
updateIfChanged(getApacheServerList(url, name));
|
||||
} catch (Exception e) {
|
||||
log.error(name, "NACOS-XXXX", "[update-serverlist] failed to update serverlist from address server!", e);
|
||||
log.error(name, "NACOS-XXXX", "[update-serverlist] failed to update serverlist from address server!",
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void updateIfChanged(List<String> newList) {
|
||||
if (null == newList || newList.isEmpty()) {
|
||||
|
||||
log.warn("NACOS-0001", LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0001", "环境问题","[update-serverlist] current serverlist from address server is empty!!!"));
|
||||
|
||||
log.warn("NACOS-0001", LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0001", "环境问题",
|
||||
"[update-serverlist] current serverlist from address server is empty!!!"));
|
||||
log.warn(name, "[update-serverlist] current serverlist from address server is empty!!!");
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* no change
|
||||
*/
|
||||
if (newList.equals(serverUrls)) {
|
||||
/**
|
||||
* no change
|
||||
*/
|
||||
if (newList.equals(serverUrls)) {
|
||||
return;
|
||||
}
|
||||
serverUrls = new ArrayList<String>(newList);
|
||||
currentServerAddr = iterator().next();
|
||||
|
||||
|
||||
EventDispatcher.fireEvent(new ServerlistChangeEvent());
|
||||
log.info(name, "[update-serverlist] serverlist updated to {}", serverUrls);
|
||||
}
|
||||
@ -253,38 +254,38 @@ public class ServerListManager {
|
||||
private List<String> getApacheServerList(String url, String name) {
|
||||
try {
|
||||
HttpResult httpResult = HttpSimpleClient.httpGet(url, null, null, null, 3000);
|
||||
|
||||
if (HttpURLConnection.HTTP_OK == httpResult.code) {
|
||||
if (DEFAULT_NAME.equals(name) ) {
|
||||
EnvUtil.setSelfEnv(httpResult.headers);
|
||||
}
|
||||
|
||||
if (HttpURLConnection.HTTP_OK == httpResult.code) {
|
||||
if (DEFAULT_NAME.equals(name)) {
|
||||
EnvUtil.setSelfEnv(httpResult.headers);
|
||||
}
|
||||
List<String> lines = IOUtils.readLines(new StringReader(httpResult.content));
|
||||
List<String> result = new ArrayList<String>(lines.size());
|
||||
for (String serverAddr : lines) {
|
||||
if (null == serverAddr || serverAddr.trim().isEmpty()) {
|
||||
continue;
|
||||
} else {
|
||||
String[] ipPort = serverAddr.trim().split(":");
|
||||
String ip = ipPort[0].trim();
|
||||
if (ipPort.length == 1) {
|
||||
result.add(ip + ":" + ParamUtil.getDefaultServerPort());
|
||||
} else {
|
||||
result.add(serverAddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
List<String> result = new ArrayList<String>(lines.size());
|
||||
for (String serverAddr : lines) {
|
||||
if (null == serverAddr || serverAddr.trim().isEmpty()) {
|
||||
continue;
|
||||
} else {
|
||||
String[] ipPort = serverAddr.trim().split(":");
|
||||
String ip = ipPort[0].trim();
|
||||
if (ipPort.length == 1) {
|
||||
result.add(ip + ":" + ParamUtil.getDefaultServerPort());
|
||||
} else {
|
||||
result.add(serverAddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
log.error(addressServerUrl, "NACOS-XXXX", "[check-serverlist] error. code={}", httpResult.code);
|
||||
return null;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("NACOS-0001", LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0001", "环境问题",e.toString()));
|
||||
log.error("NACOS-0001", LoggerHelper.getErrorCodeStr("NACOS", "NACOS-0001", "环境问题", e.toString()));
|
||||
log.error(addressServerUrl, "NACOS-XXXX", "[check-serverlist] exception. msg={}", e.toString(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String getUrlString() {
|
||||
return serverUrls.toString();
|
||||
}
|
||||
@ -294,105 +295,103 @@ public class ServerListManager {
|
||||
String split = "";
|
||||
for (String serverIp : serverIps) {
|
||||
sb.append(split);
|
||||
sb.append(serverIp);
|
||||
sb.append(serverIp.replaceAll(":", "_"));
|
||||
split = "-";
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ServerManager-" + name + "-" +getUrlString();
|
||||
return "ServerManager-" + name + "-" + getUrlString();
|
||||
}
|
||||
|
||||
public boolean contain(String ip){
|
||||
|
||||
return serverUrls.contains(ip);
|
||||
}
|
||||
public boolean contain(String ip) {
|
||||
|
||||
public void refreshCurrentServerAddr() {
|
||||
currentServerAddr = iterator().next();
|
||||
}
|
||||
return serverUrls.contains(ip);
|
||||
}
|
||||
|
||||
public String getCurrentServerAddr() {
|
||||
if (StringUtils.isBlank(currentServerAddr)) {
|
||||
currentServerAddr = iterator().next();
|
||||
}
|
||||
return currentServerAddr;
|
||||
}
|
||||
public void refreshCurrentServerAddr() {
|
||||
currentServerAddr = iterator().next();
|
||||
}
|
||||
|
||||
|
||||
public String getContentPath() {
|
||||
return contentPath;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getNamespace() {
|
||||
return namespace;
|
||||
}
|
||||
public String getCurrentServerAddr() {
|
||||
if (StringUtils.isBlank(currentServerAddr)) {
|
||||
currentServerAddr = iterator().next();
|
||||
}
|
||||
return currentServerAddr;
|
||||
}
|
||||
|
||||
public String getTenant() {
|
||||
return tenant;
|
||||
}
|
||||
|
||||
/**
|
||||
* 不同环境的名称
|
||||
*/
|
||||
private String name;
|
||||
private String namespace = "";
|
||||
private String tenant = "";
|
||||
public String getContentPath() {
|
||||
return contentPath;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getNamespace() {
|
||||
return namespace;
|
||||
}
|
||||
|
||||
public String getTenant() {
|
||||
return tenant;
|
||||
}
|
||||
|
||||
/**
|
||||
* 不同环境的名称
|
||||
*/
|
||||
private String name;
|
||||
private String namespace = "";
|
||||
private String tenant = "";
|
||||
static public final String DEFAULT_NAME = "default";
|
||||
static public final String CUSTOM_NAME = "custom";
|
||||
static public final String FIXED_NAME = "fixed";
|
||||
private int initServerlistRetryTimes = 5;
|
||||
/**
|
||||
* 和其他server的连接超时和socket超时
|
||||
*/
|
||||
/**
|
||||
* 和其他server的连接超时和socket超时
|
||||
*/
|
||||
static final int TIMEOUT = 5000;
|
||||
|
||||
|
||||
final boolean isFixed;
|
||||
boolean isStarted = false;
|
||||
private String endpoint;
|
||||
private int endpointPort = 8080;
|
||||
private String contentPath = ParamUtil.getDefaultContextPath();
|
||||
private String serverListName = ParamUtil.getDefaultNodesPath();
|
||||
boolean isStarted = false;
|
||||
private String endpoint;
|
||||
private int endpointPort = 8080;
|
||||
private String contentPath = ParamUtil.getDefaultContextPath();
|
||||
private String serverListName = ParamUtil.getDefaultNodesPath();
|
||||
volatile List<String> serverUrls = new ArrayList<String>();
|
||||
|
||||
private volatile String currentServerAddr;
|
||||
|
||||
public String serverPort = ParamUtil.getDefaultServerPort();
|
||||
|
||||
|
||||
public String serverPort = ParamUtil.getDefaultServerPort();
|
||||
|
||||
public String addressServerUrl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 对地址列表排序,同机房优先。
|
||||
* 对地址列表排序,同机房优先。
|
||||
*/
|
||||
class ServerAddressIterator implements Iterator<String> {
|
||||
|
||||
static class RandomizedServerAddress implements Comparable<RandomizedServerAddress> {
|
||||
static Random random = new Random();
|
||||
|
||||
|
||||
String serverIp;
|
||||
int priority = 0;
|
||||
int seed;
|
||||
|
||||
public RandomizedServerAddress(String ip) {
|
||||
try {
|
||||
this.serverIp = ip;
|
||||
/**
|
||||
* change random scope from 32 to Integer.MAX_VALUE to fix load balance issue
|
||||
*/
|
||||
this.seed = random.nextInt(Integer.MAX_VALUE);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public RandomizedServerAddress(String ip) {
|
||||
try {
|
||||
this.serverIp = ip;
|
||||
/**
|
||||
* change random scope from 32 to Integer.MAX_VALUE to fix load balance issue
|
||||
*/
|
||||
this.seed = random.nextInt(Integer.MAX_VALUE);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressFBWarnings("EQ_COMPARETO_USE_OBJECT_EQUALS")
|
||||
@ -425,7 +424,7 @@ class ServerAddressIterator implements Iterator<String> {
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
final List<RandomizedServerAddress> sorted;
|
||||
final Iterator<RandomizedServerAddress> iter;
|
||||
}
|
||||
|
@ -27,81 +27,79 @@ import java.util.*;
|
||||
|
||||
/**
|
||||
* 适配spas接口
|
||||
*
|
||||
* @author Nacos
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class SpasAdapter {
|
||||
|
||||
public static List<String> getSignHeaders(String resource, String secretKey) {
|
||||
List<String> header = new ArrayList<String>();
|
||||
String timeStamp = String.valueOf(System.currentTimeMillis());
|
||||
header.add("Timestamp");
|
||||
header.add(timeStamp);
|
||||
if (secretKey != null) {
|
||||
header.add("Spas-Signature");
|
||||
String signature = "";
|
||||
if (StringUtils.isBlank(resource)) {
|
||||
signature = signWithhmacSHA1Encrypt(timeStamp, secretKey);
|
||||
} else {
|
||||
signature = signWithhmacSHA1Encrypt(resource + "+" + timeStamp, secretKey);
|
||||
}
|
||||
header.add(signature);
|
||||
}
|
||||
return header;
|
||||
}
|
||||
|
||||
|
||||
public static List<String> getSignHeaders(List<String> paramValues, String secretKey) {
|
||||
if (null == paramValues) {
|
||||
return null;
|
||||
}
|
||||
Map<String, String> signMap = new HashMap<String, String>(5);
|
||||
for (Iterator<String> iter = paramValues.iterator(); iter.hasNext();) {
|
||||
String key = iter.next();
|
||||
if (TENANT_KEY.equals(key) || GROUP_KEY.equals(key)) {
|
||||
signMap.put(key, iter.next());
|
||||
} else {
|
||||
iter.next();
|
||||
}
|
||||
}
|
||||
String resource = "";
|
||||
if (signMap.size() > 1) {
|
||||
resource = signMap.get(TENANT_KEY) + "+" + signMap.get(GROUP_KEY);
|
||||
} else {
|
||||
if (!StringUtils.isBlank(signMap.get(GROUP_KEY))) {
|
||||
resource = signMap.get(GROUP_KEY);
|
||||
}
|
||||
}
|
||||
return getSignHeaders(resource, secretKey);
|
||||
}
|
||||
|
||||
public static String getSk() {
|
||||
return CredentialService.getInstance().getCredential().getSecretKey();
|
||||
}
|
||||
public static List<String> getSignHeaders(String resource, String secretKey) {
|
||||
List<String> header = new ArrayList<String>();
|
||||
String timeStamp = String.valueOf(System.currentTimeMillis());
|
||||
header.add("Timestamp");
|
||||
header.add(timeStamp);
|
||||
if (secretKey != null) {
|
||||
header.add("Spas-Signature");
|
||||
String signature = "";
|
||||
if (StringUtils.isBlank(resource)) {
|
||||
signature = signWithhmacSHA1Encrypt(timeStamp, secretKey);
|
||||
} else {
|
||||
signature = signWithhmacSHA1Encrypt(resource + "+" + timeStamp, secretKey);
|
||||
}
|
||||
header.add(signature);
|
||||
}
|
||||
return header;
|
||||
}
|
||||
|
||||
public static String getAk() {
|
||||
return CredentialService.getInstance().getCredential().getAccessKey();
|
||||
}
|
||||
|
||||
public static String signWithhmacSHA1Encrypt(String encryptText, String encryptKey) {
|
||||
try {
|
||||
byte[] data = encryptKey.getBytes("UTF-8");
|
||||
// 根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
|
||||
SecretKey secretKey = new SecretKeySpec(data, "HmacSHA1");
|
||||
// 生成一个指定 Mac 算法 的 Mac 对象
|
||||
Mac mac = Mac.getInstance("HmacSHA1");
|
||||
// 用给定密钥初始化 Mac 对象
|
||||
mac.init(secretKey);
|
||||
byte[] text = encryptText.getBytes("UTF-8");
|
||||
byte[] textFinal = mac.doFinal(text);
|
||||
// 完成 Mac 操作, base64编码,将byte数组转换为字符串
|
||||
return new String(Base64.encodeBase64(textFinal), Constants.ENCODE);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("signWithhmacSHA1Encrypt fail", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static String GROUP_KEY = "group";
|
||||
private static String TENANT_KEY = "tenant";
|
||||
public static List<String> getSignHeaders(List<String> paramValues, String secretKey) {
|
||||
if (null == paramValues) {
|
||||
return null;
|
||||
}
|
||||
Map<String, String> signMap = new HashMap<String, String>(5);
|
||||
for (Iterator<String> iter = paramValues.iterator(); iter.hasNext(); ) {
|
||||
String key = iter.next();
|
||||
if (TENANT_KEY.equals(key) || GROUP_KEY.equals(key)) {
|
||||
signMap.put(key, iter.next());
|
||||
} else {
|
||||
iter.next();
|
||||
}
|
||||
}
|
||||
String resource = "";
|
||||
if (signMap.size() > 1) {
|
||||
resource = signMap.get(TENANT_KEY) + "+" + signMap.get(GROUP_KEY);
|
||||
} else {
|
||||
if (!StringUtils.isBlank(signMap.get(GROUP_KEY))) {
|
||||
resource = signMap.get(GROUP_KEY);
|
||||
}
|
||||
}
|
||||
return getSignHeaders(resource, secretKey);
|
||||
}
|
||||
|
||||
public static String getSk() {
|
||||
return CredentialService.getInstance().getCredential().getSecretKey();
|
||||
}
|
||||
|
||||
public static String getAk() {
|
||||
return CredentialService.getInstance().getCredential().getAccessKey();
|
||||
}
|
||||
|
||||
public static String signWithhmacSHA1Encrypt(String encryptText, String encryptKey) {
|
||||
try {
|
||||
byte[] data = encryptKey.getBytes("UTF-8");
|
||||
// 根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
|
||||
SecretKey secretKey = new SecretKeySpec(data, "HmacSHA1");
|
||||
// 生成一个指定 Mac 算法 的 Mac 对象
|
||||
Mac mac = Mac.getInstance("HmacSHA1");
|
||||
// 用给定密钥初始化 Mac 对象
|
||||
mac.init(secretKey);
|
||||
byte[] text = encryptText.getBytes("UTF-8");
|
||||
byte[] textFinal = mac.doFinal(text);
|
||||
// 完成 Mac 操作, base64编码,将byte数组转换为字符串
|
||||
return new String(Base64.encodeBase64(textFinal), Constants.ENCODE);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("signWithhmacSHA1Encrypt fail", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static String GROUP_KEY = "group";
|
||||
private static String TENANT_KEY = "tenant";
|
||||
}
|
||||
|
@ -21,28 +21,27 @@ import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
/**
|
||||
* Time Service
|
||||
* @author Nacos
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class TimerService {
|
||||
|
||||
static public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay,
|
||||
long delay, TimeUnit unit) {
|
||||
long delay, TimeUnit unit) {
|
||||
return scheduledExecutor.scheduleWithFixedDelay(command, initialDelay, delay, unit);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("PMD.ThreadPoolCreationRule")
|
||||
static ScheduledExecutorService scheduledExecutor = Executors
|
||||
.newSingleThreadScheduledExecutor(new ThreadFactory() {
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread t = new Thread(r);
|
||||
t.setName("com.alibaba.nacos.client.Timer");
|
||||
t.setDaemon(true);
|
||||
return t;
|
||||
}
|
||||
});
|
||||
|
||||
.newSingleThreadScheduledExecutor(new ThreadFactory() {
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread t = new Thread(r);
|
||||
t.setName("com.alibaba.nacos.client.Timer");
|
||||
t.setDaemon(true);
|
||||
return t;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -26,14 +26,13 @@ import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Properties Listener
|
||||
*
|
||||
* @author Nacos
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule")
|
||||
public abstract class PropertiesListener extends AbstractListener {
|
||||
final static public Logger log = LogUtils.logger(PropertiesListener.class);
|
||||
|
||||
final static public Logger log = LogUtils.logger(PropertiesListener.class);
|
||||
|
||||
public void receiveConfigInfo(String configInfo) {
|
||||
if (StringUtils.isEmpty(configInfo)) {
|
||||
return;
|
||||
@ -43,19 +42,17 @@ public abstract class PropertiesListener extends AbstractListener {
|
||||
try {
|
||||
properties.load(new StringReader(configInfo));
|
||||
innerReceive(properties);
|
||||
}
|
||||
catch (IOException e) {
|
||||
log.error("NACOS-XXXX","load properties error:" + configInfo, e);
|
||||
} catch (IOException e) {
|
||||
log.error("NACOS-XXXX", "load properties error:" + configInfo, e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* properties type for receiver
|
||||
*
|
||||
* @param properties
|
||||
* properties
|
||||
*/
|
||||
public abstract void innerReceive(Properties properties);
|
||||
/**
|
||||
* properties type for receiver
|
||||
*
|
||||
* @param properties properties
|
||||
*/
|
||||
public abstract void innerReceive(Properties properties);
|
||||
|
||||
}
|
||||
|
@ -30,217 +30,199 @@ import java.nio.charset.CharsetDecoder;
|
||||
|
||||
/**
|
||||
* concurrent disk util;op file with file lock
|
||||
*
|
||||
* @author configCenter
|
||||
*
|
||||
* @author configCenter
|
||||
*/
|
||||
public class ConcurrentDiskUtil {
|
||||
|
||||
/**
|
||||
* get file content
|
||||
*
|
||||
* @param path
|
||||
* file path
|
||||
* @param charsetName
|
||||
* charsetName
|
||||
* @return content
|
||||
* @throws IOException
|
||||
* IOException
|
||||
*/
|
||||
public static String getFileContent(String path, String charsetName)
|
||||
throws IOException {
|
||||
File file = new File(path);
|
||||
return getFileContent(file, charsetName);
|
||||
}
|
||||
/**
|
||||
* get file content
|
||||
*
|
||||
* @param path file path
|
||||
* @param charsetName charsetName
|
||||
* @return content
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
public static String getFileContent(String path, String charsetName)
|
||||
throws IOException {
|
||||
File file = new File(path);
|
||||
return getFileContent(file, charsetName);
|
||||
}
|
||||
|
||||
/**
|
||||
* get file content
|
||||
*
|
||||
* @param file
|
||||
* file
|
||||
* @param charsetName
|
||||
* charsetName
|
||||
* @return content
|
||||
* @throws IOException
|
||||
* IOException
|
||||
*/
|
||||
public static String getFileContent(File file, String charsetName)
|
||||
throws IOException {
|
||||
RandomAccessFile fis = null;
|
||||
FileLock rlock = null;
|
||||
try {
|
||||
fis = new RandomAccessFile(file, "r");
|
||||
FileChannel fcin = fis.getChannel();
|
||||
int i = 0;
|
||||
do {
|
||||
try {
|
||||
rlock = fcin.tryLock(0L, Long.MAX_VALUE, true);
|
||||
} catch (Exception e) {
|
||||
++i;
|
||||
if (i > RETRY_COUNT) {
|
||||
log.error("read {} fail;retryed time:{}",
|
||||
file.getName(), i);
|
||||
throw new IOException("read " + file.getAbsolutePath()
|
||||
+ " conflict");
|
||||
}
|
||||
sleep(SLEEP_BASETIME * i);
|
||||
log.warn("read {} conflict;retry time:{}", file.getName(),
|
||||
i);
|
||||
}
|
||||
} while (null == rlock);
|
||||
int fileSize = (int) fcin.size();
|
||||
ByteBuffer byteBuffer = ByteBuffer.allocate(fileSize);
|
||||
fcin.read(byteBuffer);
|
||||
byteBuffer.flip();
|
||||
return byteBufferToString(byteBuffer, charsetName);
|
||||
} finally {
|
||||
if (rlock != null) {
|
||||
rlock.release();
|
||||
rlock = null;
|
||||
}
|
||||
if (fis != null) {
|
||||
fis.close();
|
||||
fis = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* get file content
|
||||
*
|
||||
* @param file file
|
||||
* @param charsetName charsetName
|
||||
* @return content
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
public static String getFileContent(File file, String charsetName)
|
||||
throws IOException {
|
||||
RandomAccessFile fis = null;
|
||||
FileLock rlock = null;
|
||||
try {
|
||||
fis = new RandomAccessFile(file, "r");
|
||||
FileChannel fcin = fis.getChannel();
|
||||
int i = 0;
|
||||
do {
|
||||
try {
|
||||
rlock = fcin.tryLock(0L, Long.MAX_VALUE, true);
|
||||
} catch (Exception e) {
|
||||
++i;
|
||||
if (i > RETRY_COUNT) {
|
||||
log.error("read {} fail;retryed time:{}",
|
||||
file.getName(), i);
|
||||
throw new IOException("read " + file.getAbsolutePath()
|
||||
+ " conflict");
|
||||
}
|
||||
sleep(SLEEP_BASETIME * i);
|
||||
log.warn("read {} conflict;retry time:{}", file.getName(),
|
||||
i);
|
||||
}
|
||||
} while (null == rlock);
|
||||
int fileSize = (int)fcin.size();
|
||||
ByteBuffer byteBuffer = ByteBuffer.allocate(fileSize);
|
||||
fcin.read(byteBuffer);
|
||||
byteBuffer.flip();
|
||||
return byteBufferToString(byteBuffer, charsetName);
|
||||
} finally {
|
||||
if (rlock != null) {
|
||||
rlock.release();
|
||||
rlock = null;
|
||||
}
|
||||
if (fis != null) {
|
||||
fis.close();
|
||||
fis = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* write file content
|
||||
*
|
||||
* @param path
|
||||
* file path
|
||||
* @param content
|
||||
* content
|
||||
* @param charsetName
|
||||
* charsetName
|
||||
* @return whether write ok
|
||||
* @throws IOException
|
||||
* IOException
|
||||
*/
|
||||
public static Boolean writeFileContent(String path, String content,
|
||||
String charsetName) throws IOException {
|
||||
File file = new File(path);
|
||||
return writeFileContent(file, content, charsetName);
|
||||
}
|
||||
/**
|
||||
* write file content
|
||||
*
|
||||
* @param path file path
|
||||
* @param content content
|
||||
* @param charsetName charsetName
|
||||
* @return whether write ok
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
public static Boolean writeFileContent(String path, String content,
|
||||
String charsetName) throws IOException {
|
||||
File file = new File(path);
|
||||
return writeFileContent(file, content, charsetName);
|
||||
}
|
||||
|
||||
/**
|
||||
* write file content
|
||||
*
|
||||
* @param file
|
||||
* file
|
||||
* @param content
|
||||
* content
|
||||
* @param charsetName
|
||||
* charsetName
|
||||
* @return whether write ok
|
||||
* @throws IOException
|
||||
* IOException
|
||||
*/
|
||||
public static Boolean writeFileContent(File file, String content,
|
||||
String charsetName) throws IOException {
|
||||
if (!file.exists()) {
|
||||
boolean isCreateOk = file.createNewFile();
|
||||
if (!isCreateOk) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
FileChannel channel = null;
|
||||
FileLock lock = null;
|
||||
RandomAccessFile raf = null;
|
||||
try {
|
||||
raf = new RandomAccessFile(file, "rw");
|
||||
channel = raf.getChannel();
|
||||
int i = 0;
|
||||
do {
|
||||
try {
|
||||
lock = channel.tryLock();
|
||||
} catch (Exception e) {
|
||||
++i;
|
||||
if (i > RETRY_COUNT) {
|
||||
log.error("write {} fail;retryed time:{}",
|
||||
file.getName(), i);
|
||||
throw new IOException("write " + file.getAbsolutePath()
|
||||
+ " conflict");
|
||||
}
|
||||
sleep(SLEEP_BASETIME * i);
|
||||
log.warn("write {} conflict;retry time:{}", file.getName(),
|
||||
i);
|
||||
}
|
||||
} while (null == lock);
|
||||
/**
|
||||
* write file content
|
||||
*
|
||||
* @param file file
|
||||
* @param content content
|
||||
* @param charsetName charsetName
|
||||
* @return whether write ok
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
public static Boolean writeFileContent(File file, String content,
|
||||
String charsetName) throws IOException {
|
||||
if (!file.exists()) {
|
||||
boolean isCreateOk = file.createNewFile();
|
||||
if (!isCreateOk) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
FileChannel channel = null;
|
||||
FileLock lock = null;
|
||||
RandomAccessFile raf = null;
|
||||
try {
|
||||
raf = new RandomAccessFile(file, "rw");
|
||||
channel = raf.getChannel();
|
||||
int i = 0;
|
||||
do {
|
||||
try {
|
||||
lock = channel.tryLock();
|
||||
} catch (Exception e) {
|
||||
++i;
|
||||
if (i > RETRY_COUNT) {
|
||||
log.error("write {} fail;retryed time:{}",
|
||||
file.getName(), i);
|
||||
throw new IOException("write " + file.getAbsolutePath()
|
||||
+ " conflict");
|
||||
}
|
||||
sleep(SLEEP_BASETIME * i);
|
||||
log.warn("write {} conflict;retry time:{}", file.getName(),
|
||||
i);
|
||||
}
|
||||
} while (null == lock);
|
||||
|
||||
ByteBuffer sendBuffer = ByteBuffer.wrap(content
|
||||
.getBytes(charsetName));
|
||||
while (sendBuffer.hasRemaining()) {
|
||||
channel.write(sendBuffer);
|
||||
}
|
||||
channel.truncate(content.length());
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new IOException("file not exist");
|
||||
} finally {
|
||||
if (lock != null) {
|
||||
try {
|
||||
lock.release();
|
||||
lock = null;
|
||||
} catch (IOException e) {
|
||||
log.warn("close wrong", e);
|
||||
}
|
||||
}
|
||||
if (channel != null) {
|
||||
try {
|
||||
channel.close();
|
||||
channel = null;
|
||||
} catch (IOException e) {
|
||||
log.warn("close wrong", e);
|
||||
}
|
||||
}
|
||||
if (raf != null) {
|
||||
try {
|
||||
raf.close();
|
||||
raf = null;
|
||||
} catch (IOException e) {
|
||||
log.warn("close wrong", e);
|
||||
}
|
||||
}
|
||||
ByteBuffer sendBuffer = ByteBuffer.wrap(content
|
||||
.getBytes(charsetName));
|
||||
while (sendBuffer.hasRemaining()) {
|
||||
channel.write(sendBuffer);
|
||||
}
|
||||
channel.truncate(content.length());
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new IOException("file not exist");
|
||||
} finally {
|
||||
if (lock != null) {
|
||||
try {
|
||||
lock.release();
|
||||
lock = null;
|
||||
} catch (IOException e) {
|
||||
log.warn("close wrong", e);
|
||||
}
|
||||
}
|
||||
if (channel != null) {
|
||||
try {
|
||||
channel.close();
|
||||
channel = null;
|
||||
} catch (IOException e) {
|
||||
log.warn("close wrong", e);
|
||||
}
|
||||
}
|
||||
if (raf != null) {
|
||||
try {
|
||||
raf.close();
|
||||
raf = null;
|
||||
} catch (IOException e) {
|
||||
log.warn("close wrong", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* transfer ByteBuffer to String
|
||||
*
|
||||
* @param buffer
|
||||
* buffer
|
||||
* @param charsetName
|
||||
* charsetName
|
||||
* @return String
|
||||
* @throws IOException
|
||||
* IOException
|
||||
*/
|
||||
public static String byteBufferToString(ByteBuffer buffer,
|
||||
String charsetName) throws IOException {
|
||||
Charset charset = null;
|
||||
CharsetDecoder decoder = null;
|
||||
CharBuffer charBuffer = null;
|
||||
charset = Charset.forName(charsetName);
|
||||
decoder = charset.newDecoder();
|
||||
charBuffer = decoder.decode(buffer.asReadOnlyBuffer());
|
||||
return charBuffer.toString();
|
||||
}
|
||||
/**
|
||||
* transfer ByteBuffer to String
|
||||
*
|
||||
* @param buffer buffer
|
||||
* @param charsetName charsetName
|
||||
* @return String
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
public static String byteBufferToString(ByteBuffer buffer,
|
||||
String charsetName) throws IOException {
|
||||
Charset charset = null;
|
||||
CharsetDecoder decoder = null;
|
||||
CharBuffer charBuffer = null;
|
||||
charset = Charset.forName(charsetName);
|
||||
decoder = charset.newDecoder();
|
||||
charBuffer = decoder.decode(buffer.asReadOnlyBuffer());
|
||||
return charBuffer.toString();
|
||||
}
|
||||
|
||||
private static void sleep(int time) {
|
||||
try {
|
||||
Thread.sleep(time);
|
||||
} catch (InterruptedException e) {
|
||||
log.warn("sleep wrong", e);
|
||||
}
|
||||
}
|
||||
private static void sleep(int time) {
|
||||
try {
|
||||
Thread.sleep(time);
|
||||
} catch (InterruptedException e) {
|
||||
log.warn("sleep wrong", e);
|
||||
}
|
||||
}
|
||||
|
||||
static final public Logger log = LogUtils.logger(ConcurrentDiskUtil.class);
|
||||
static final int RETRY_COUNT = 10;
|
||||
/**
|
||||
* ms
|
||||
*/
|
||||
static final int SLEEP_BASETIME = 10;
|
||||
static final public Logger log = LogUtils.logger(ConcurrentDiskUtil.class);
|
||||
static final int RETRY_COUNT = 10;
|
||||
/**
|
||||
* ms
|
||||
*/
|
||||
static final int SLEEP_BASETIME = 10;
|
||||
}
|
||||
|
@ -21,9 +21,8 @@ import static com.alibaba.nacos.api.common.Constants.WORD_SEPARATOR;
|
||||
|
||||
/**
|
||||
* Content Util
|
||||
*
|
||||
* @author Nacos
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class ContentUtils {
|
||||
|
||||
@ -43,7 +42,6 @@ public class ContentUtils {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String getContentIdentity(String content) {
|
||||
int index = content.indexOf(WORD_SEPARATOR);
|
||||
if (index == -1) {
|
||||
@ -52,7 +50,6 @@ public class ContentUtils {
|
||||
return content.substring(0, index);
|
||||
}
|
||||
|
||||
|
||||
public static String getContent(String content) {
|
||||
int index = content.indexOf(WORD_SEPARATOR);
|
||||
if (index == -1) {
|
||||
@ -61,18 +58,15 @@ public class ContentUtils {
|
||||
return content.substring(index + 1);
|
||||
}
|
||||
|
||||
|
||||
public static String truncateContent(String content) {
|
||||
if (content == null) {
|
||||
return "";
|
||||
}
|
||||
else if (content.length() <= SHOW_CONTENT_SIZE) {
|
||||
} else if (content.length() <= SHOW_CONTENT_SIZE) {
|
||||
return content;
|
||||
}
|
||||
else {
|
||||
return content.substring(0, SHOW_CONTENT_SIZE) + "...";
|
||||
} else {
|
||||
return content.substring(0, SHOW_CONTENT_SIZE) + "...";
|
||||
}
|
||||
}
|
||||
|
||||
private static int SHOW_CONTENT_SIZE = 100;
|
||||
private static int SHOW_CONTENT_SIZE = 100;
|
||||
}
|
||||
|
@ -21,21 +21,19 @@ import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* IO Util
|
||||
*
|
||||
* @author Nacos
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
|
||||
public class IOUtils {
|
||||
|
||||
static public String toString(InputStream input, String encoding) throws IOException {
|
||||
return (null == encoding) ? toString(new InputStreamReader(input, Constants.ENCODE))
|
||||
: toString(new InputStreamReader(input, encoding));
|
||||
: toString(new InputStreamReader(input, encoding));
|
||||
}
|
||||
|
||||
|
||||
static public String toString(Reader reader) throws IOException {
|
||||
CharArrayWriter sw = new CharArrayWriter();
|
||||
copy(reader, sw);
|
||||
@ -45,7 +43,7 @@ public class IOUtils {
|
||||
static public long copy(Reader input, Writer output) throws IOException {
|
||||
char[] buffer = new char[1 << 12];
|
||||
long count = 0;
|
||||
for (int n = 0; (n = input.read(buffer)) >= 0;) {
|
||||
for (int n = 0; (n = input.read(buffer)) >= 0; ) {
|
||||
output.write(buffer, 0, n);
|
||||
count += n;
|
||||
}
|
||||
@ -59,7 +57,7 @@ public class IOUtils {
|
||||
BufferedReader reader = toBufferedReader(input);
|
||||
List<String> list = new ArrayList<String>();
|
||||
String line = null;
|
||||
for (;;) {
|
||||
for (; ; ) {
|
||||
line = reader.readLine();
|
||||
if (null != line) {
|
||||
list.add(line);
|
||||
@ -71,8 +69,8 @@ public class IOUtils {
|
||||
}
|
||||
|
||||
static private BufferedReader toBufferedReader(Reader reader) {
|
||||
return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(
|
||||
reader);
|
||||
return reader instanceof BufferedReader ? (BufferedReader)reader : new BufferedReader(
|
||||
reader);
|
||||
}
|
||||
|
||||
public static void delete(File fileOrDir) throws IOException {
|
||||
@ -82,16 +80,16 @@ public class IOUtils {
|
||||
|
||||
if (fileOrDir.isDirectory()) {
|
||||
cleanDirectory(fileOrDir);
|
||||
} else {
|
||||
if (fileOrDir.exists()) {
|
||||
boolean isDeleteOk = fileOrDir.delete();
|
||||
if (!isDeleteOk) {
|
||||
throw new IOException("delete fail");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (fileOrDir.exists()) {
|
||||
boolean isDeleteOk = fileOrDir.delete();
|
||||
if (!isDeleteOk) {
|
||||
throw new IOException("delete fail");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 清理目录下的内容
|
||||
*/
|
||||
@ -107,10 +105,10 @@ public class IOUtils {
|
||||
}
|
||||
|
||||
File[] files = directory.listFiles();
|
||||
/**
|
||||
* null if security restricted
|
||||
*/
|
||||
if (files == null) {
|
||||
/**
|
||||
* null if security restricted
|
||||
*/
|
||||
if (files == null) {
|
||||
throw new IOException("Failed to list contents of " + directory);
|
||||
}
|
||||
|
||||
@ -129,7 +127,7 @@ public class IOUtils {
|
||||
}
|
||||
|
||||
public static void writeStringToFile(File file, String data, String encoding)
|
||||
throws IOException {
|
||||
throws IOException {
|
||||
OutputStream os = null;
|
||||
try {
|
||||
os = new FileOutputStream(file);
|
||||
|
@ -19,31 +19,30 @@ import com.alibaba.nacos.client.logger.Logger;
|
||||
|
||||
/**
|
||||
* Get jvm config
|
||||
*
|
||||
* @author Nacos
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
|
||||
public class JVMUtil {
|
||||
|
||||
/**
|
||||
* whether is multi instance
|
||||
*
|
||||
* @return whether multi
|
||||
*/
|
||||
public static Boolean isMultiInstance() {
|
||||
return isMultiInstance;
|
||||
}
|
||||
/**
|
||||
* whether is multi instance
|
||||
*
|
||||
* @return whether multi
|
||||
*/
|
||||
public static Boolean isMultiInstance() {
|
||||
return isMultiInstance;
|
||||
}
|
||||
|
||||
private static Boolean isMultiInstance = false;
|
||||
private static String TRUE = "true";
|
||||
static final public Logger log = LogUtils.logger(JVMUtil.class);
|
||||
private static Boolean isMultiInstance = false;
|
||||
private static String TRUE = "true";
|
||||
static final public Logger log = LogUtils.logger(JVMUtil.class);
|
||||
|
||||
static {
|
||||
String multiDeploy = System.getProperty("isMultiInstance", "false");
|
||||
if (TRUE.equals(multiDeploy)) {
|
||||
isMultiInstance = true;
|
||||
}
|
||||
log.info("isMultiInstance:{}", isMultiInstance);
|
||||
}
|
||||
static {
|
||||
String multiDeploy = System.getProperty("isMultiInstance", "false");
|
||||
if (TRUE.equals(multiDeploy)) {
|
||||
isMultiInstance = true;
|
||||
}
|
||||
log.info("isMultiInstance:{}", isMultiInstance);
|
||||
}
|
||||
}
|
||||
|
@ -22,38 +22,38 @@ import com.alibaba.nacos.client.logger.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Log Util
|
||||
*
|
||||
* @author Nacos
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class LogUtils {
|
||||
|
||||
static int JM_LOG_RETAIN_COUNT = 7;
|
||||
static String JM_LOG_FILE_SIZE = "10MB";
|
||||
static int JM_LOG_RETAIN_COUNT = 7;
|
||||
static String JM_LOG_FILE_SIZE = "10MB";
|
||||
|
||||
static {
|
||||
String tmp = "7";
|
||||
String tmp = "7";
|
||||
try {
|
||||
/**
|
||||
* change timeout from 100 to 200
|
||||
*/
|
||||
tmp = System.getProperty("JM.LOG.RETAIN.COUNT","7");
|
||||
/**
|
||||
* change timeout from 100 to 200
|
||||
*/
|
||||
tmp = System.getProperty("JM.LOG.RETAIN.COUNT", "7");
|
||||
JM_LOG_RETAIN_COUNT = Integer.parseInt(tmp);
|
||||
} catch (NumberFormatException e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}
|
||||
|
||||
JM_LOG_FILE_SIZE = System.getProperty("JM.LOG.FILE.SIZE","10MB");
|
||||
|
||||
|
||||
JM_LOG_FILE_SIZE = System.getProperty("JM.LOG.FILE.SIZE", "10MB");
|
||||
|
||||
// logger init
|
||||
Logger logger = LoggerFactory.getLogger("com.alibaba.nacos.client.config");
|
||||
logger.setLevel(Level.INFO);
|
||||
logger.setAdditivity(false);
|
||||
logger.activateAppenderWithSizeRolling("nacos", "config.log", Constants.ENCODE, JM_LOG_FILE_SIZE, JM_LOG_RETAIN_COUNT);
|
||||
logger.activateAppenderWithSizeRolling("nacos", "config.log", Constants.ENCODE, JM_LOG_FILE_SIZE,
|
||||
JM_LOG_RETAIN_COUNT);
|
||||
}
|
||||
|
||||
public static Logger logger(Class<?> clazz) {
|
||||
return LoggerFactory.getLogger(clazz);
|
||||
}
|
||||
public static Logger logger(Class<?> clazz) {
|
||||
return LoggerFactory.getLogger(clazz);
|
||||
}
|
||||
}
|
||||
|
@ -25,16 +25,16 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* MD5 util
|
||||
*
|
||||
* @author Nacos
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
|
||||
public class MD5 {
|
||||
private static int DIGITS_SIZE = 16;
|
||||
private static char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
private static int DIGITS_SIZE = 16;
|
||||
private static char[] digits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||
|
||||
private static Map<Character, Integer> rDigits = new HashMap<Character, Integer>(16);
|
||||
|
||||
static {
|
||||
for (int i = 0; i < digits.length; ++i) {
|
||||
rDigits.put(digits[i], i);
|
||||
@ -45,41 +45,34 @@ public class MD5 {
|
||||
private MessageDigest mHasher;
|
||||
private ReentrantLock opLock = new ReentrantLock();
|
||||
|
||||
|
||||
private MD5() {
|
||||
try {
|
||||
mHasher = MessageDigest.getInstance("md5");
|
||||
}
|
||||
catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static MD5 getInstance() {
|
||||
return me;
|
||||
}
|
||||
|
||||
|
||||
public String getMD5String(String content) {
|
||||
return bytes2string(hash(content));
|
||||
}
|
||||
|
||||
|
||||
public String getMD5String(byte[] content) {
|
||||
return bytes2string(hash(content));
|
||||
}
|
||||
|
||||
|
||||
public byte[] getMD5Bytes(byte[] content) {
|
||||
return hash(content);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 对字符串进行md5
|
||||
*
|
||||
*
|
||||
* @param str
|
||||
* @return md5 byte[16]
|
||||
*/
|
||||
@ -91,20 +84,17 @@ public class MD5 {
|
||||
throw new IllegalArgumentException("md5 need");
|
||||
}
|
||||
return bt;
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException("unsupported utf-8 encoding", e);
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
opLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 对二进制数据进行md5
|
||||
*
|
||||
* @param str
|
||||
*
|
||||
* @param data
|
||||
* @return md5 byte[16]
|
||||
*/
|
||||
public byte[] hash(byte[] data) {
|
||||
@ -115,16 +105,14 @@ public class MD5 {
|
||||
throw new IllegalArgumentException("md5 need");
|
||||
}
|
||||
return bt;
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
opLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将一个字节数组转化为可见的字符串
|
||||
*
|
||||
*
|
||||
* @param bt
|
||||
* @return
|
||||
*/
|
||||
@ -141,5 +129,4 @@ public class MD5 {
|
||||
return new String(out);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -23,18 +23,16 @@ import com.alibaba.nacos.client.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* Param check util
|
||||
*
|
||||
*
|
||||
* @author Nacos
|
||||
*
|
||||
*/
|
||||
public class ParamUtils {
|
||||
|
||||
private static char[] validChars = new char[] { '_', '-', '.', ':' };
|
||||
|
||||
private static char[] validChars = new char[] {'_', '-', '.', ':'};
|
||||
|
||||
/**
|
||||
* 白名单的方式检查, 合法的参数只能包含字母、数字、以及validChars中的字符, 并且不能为空
|
||||
*
|
||||
*
|
||||
* @param param
|
||||
* @return
|
||||
*/
|
||||
@ -47,18 +45,15 @@ public class ParamUtils {
|
||||
char ch = param.charAt(i);
|
||||
if (Character.isLetterOrDigit(ch)) {
|
||||
continue;
|
||||
}
|
||||
else if (isValidChar(ch)) {
|
||||
} else if (isValidChar(ch)) {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private static boolean isValidChar(char ch) {
|
||||
for (char c : validChars) {
|
||||
if (c == ch) {
|
||||
@ -67,88 +62,88 @@ public class ParamUtils {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void checkKeyParam(String dataId, String group) throws NacosException {
|
||||
if (StringUtils.isBlank(dataId) || !ParamUtils.isValid(dataId)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "dataId invalid");
|
||||
}
|
||||
if (StringUtils.isBlank(group) || !ParamUtils.isValid(group)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "group invalid");
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkTDG(String tenant, String dataId, String group) throws NacosException {
|
||||
checkTenant(tenant);
|
||||
if (StringUtils.isBlank(dataId) || !ParamUtils.isValid(dataId)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "dataId invalid");
|
||||
}
|
||||
if (StringUtils.isBlank(group) || !ParamUtils.isValid(group)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "group invalid");
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkKeyParam(String dataId, String group, String datumId)
|
||||
throws NacosException {
|
||||
if (StringUtils.isBlank(dataId) || !ParamUtils.isValid(dataId)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "dataId invalid");
|
||||
}
|
||||
if (StringUtils.isBlank(group) || !ParamUtils.isValid(group)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "group invalid");
|
||||
}
|
||||
if (StringUtils.isBlank(datumId) || !ParamUtils.isValid(datumId)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "datumId invalid");
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkKeyParam(List<String> dataIds, String group) throws NacosException {
|
||||
if (dataIds == null || dataIds.size() == 0) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "dataIds invalid");
|
||||
}
|
||||
for (String dataId : dataIds) {
|
||||
if (StringUtils.isBlank(dataId) || !ParamUtils.isValid(dataId)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "dataId invalid");
|
||||
}
|
||||
}
|
||||
if (StringUtils.isBlank(group) || !ParamUtils.isValid(group)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "group invalid");
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkParam(String dataId, String group, String content) throws NacosException {
|
||||
checkKeyParam(dataId, group);
|
||||
if (StringUtils.isBlank(content)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "content invalid");
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkParam(String dataId, String group, String datumId, String content) throws NacosException {
|
||||
checkKeyParam(dataId, group, datumId);
|
||||
if (StringUtils.isBlank(content)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "content invalid");
|
||||
}
|
||||
}
|
||||
public static void checkKeyParam(String dataId, String group) throws NacosException {
|
||||
if (StringUtils.isBlank(dataId) || !ParamUtils.isValid(dataId)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "dataId invalid");
|
||||
}
|
||||
if (StringUtils.isBlank(group) || !ParamUtils.isValid(group)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "group invalid");
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkTenant(String tenant) throws NacosException {
|
||||
if (StringUtils.isBlank(tenant) || !ParamUtils.isValid(tenant)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "tenant invalid");
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkBetaIps(String betaIps) throws NacosException {
|
||||
if (StringUtils.isBlank(betaIps)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "betaIps invalid");
|
||||
}
|
||||
String[] ipsArr = betaIps.split(",");
|
||||
for (String ip : ipsArr) {
|
||||
if (!IPUtil.isIPV4(ip)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "betaIps invalid");
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void checkTDG(String tenant, String dataId, String group) throws NacosException {
|
||||
checkTenant(tenant);
|
||||
if (StringUtils.isBlank(dataId) || !ParamUtils.isValid(dataId)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "dataId invalid");
|
||||
}
|
||||
if (StringUtils.isBlank(group) || !ParamUtils.isValid(group)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "group invalid");
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkContent(String content) throws NacosException {
|
||||
if (StringUtils.isBlank(content)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "content invalid");
|
||||
}
|
||||
}
|
||||
public static void checkKeyParam(String dataId, String group, String datumId)
|
||||
throws NacosException {
|
||||
if (StringUtils.isBlank(dataId) || !ParamUtils.isValid(dataId)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "dataId invalid");
|
||||
}
|
||||
if (StringUtils.isBlank(group) || !ParamUtils.isValid(group)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "group invalid");
|
||||
}
|
||||
if (StringUtils.isBlank(datumId) || !ParamUtils.isValid(datumId)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "datumId invalid");
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkKeyParam(List<String> dataIds, String group) throws NacosException {
|
||||
if (dataIds == null || dataIds.size() == 0) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "dataIds invalid");
|
||||
}
|
||||
for (String dataId : dataIds) {
|
||||
if (StringUtils.isBlank(dataId) || !ParamUtils.isValid(dataId)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "dataId invalid");
|
||||
}
|
||||
}
|
||||
if (StringUtils.isBlank(group) || !ParamUtils.isValid(group)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "group invalid");
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkParam(String dataId, String group, String content) throws NacosException {
|
||||
checkKeyParam(dataId, group);
|
||||
if (StringUtils.isBlank(content)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "content invalid");
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkParam(String dataId, String group, String datumId, String content) throws NacosException {
|
||||
checkKeyParam(dataId, group, datumId);
|
||||
if (StringUtils.isBlank(content)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "content invalid");
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkTenant(String tenant) throws NacosException {
|
||||
if (StringUtils.isBlank(tenant) || !ParamUtils.isValid(tenant)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "tenant invalid");
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkBetaIps(String betaIps) throws NacosException {
|
||||
if (StringUtils.isBlank(betaIps)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "betaIps invalid");
|
||||
}
|
||||
String[] ipsArr = betaIps.split(",");
|
||||
for (String ip : ipsArr) {
|
||||
if (!IPUtil.isIPV4(ip)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "betaIps invalid");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkContent(String content) throws NacosException {
|
||||
if (StringUtils.isBlank(content)) {
|
||||
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, "content invalid");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,24 +19,23 @@ import com.alibaba.nacos.client.config.impl.LocalConfigInfoProcessor;
|
||||
|
||||
/**
|
||||
* Snapshot switch
|
||||
*
|
||||
* @author Nacos
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class SnapShotSwitch {
|
||||
|
||||
/**
|
||||
* whether use local cache
|
||||
*/
|
||||
private static Boolean isSnapShot = true;
|
||||
/**
|
||||
* whether use local cache
|
||||
*/
|
||||
private static Boolean isSnapShot = true;
|
||||
|
||||
public static Boolean getIsSnapShot() {
|
||||
return isSnapShot;
|
||||
}
|
||||
public static Boolean getIsSnapShot() {
|
||||
return isSnapShot;
|
||||
}
|
||||
|
||||
public static void setIsSnapShot(Boolean isSnapShot) {
|
||||
SnapShotSwitch.isSnapShot = isSnapShot;
|
||||
LocalConfigInfoProcessor.cleanAllSnapshot();
|
||||
}
|
||||
|
||||
public static void setIsSnapShot(Boolean isSnapShot) {
|
||||
SnapShotSwitch.isSnapShot = isSnapShot;
|
||||
LocalConfigInfoProcessor.cleanAllSnapshot();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,26 +19,25 @@ import com.alibaba.nacos.client.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* Tenant Util
|
||||
*
|
||||
* @author Nacos
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
public class TenantUtil {
|
||||
|
||||
static String userTenant = "";
|
||||
|
||||
static {
|
||||
userTenant = System.getProperty("tenant.id", "");
|
||||
if (StringUtils.isBlank(userTenant)) {
|
||||
userTenant = System.getProperty("acm.namespace", "");
|
||||
}
|
||||
}
|
||||
static String userTenant = "";
|
||||
|
||||
public static String getUserTenant() {
|
||||
return userTenant;
|
||||
}
|
||||
static {
|
||||
userTenant = System.getProperty("tenant.id", "");
|
||||
if (StringUtils.isBlank(userTenant)) {
|
||||
userTenant = System.getProperty("acm.namespace", "");
|
||||
}
|
||||
}
|
||||
|
||||
public static void setUserTenant(String userTenant) {
|
||||
TenantUtil.userTenant = userTenant;
|
||||
}
|
||||
public static String getUserTenant() {
|
||||
return userTenant;
|
||||
}
|
||||
|
||||
public static void setUserTenant(String userTenant) {
|
||||
TenantUtil.userTenant = userTenant;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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/";
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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<String, CredentialService> instances = new ConcurrentHashMap<String, CredentialService>();
|
||||
static final public Logger log = LogUtils.logger(CredentialService.class);
|
||||
private static ConcurrentHashMap<String, CredentialService> instances
|
||||
= new ConcurrentHashMap<String, CredentialService>();
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)));
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -20,7 +20,7 @@ import com.alibaba.nacos.client.logger.option.ActivateOption;
|
||||
/**
|
||||
* <pre>
|
||||
* 阿里中间件日志API,用于输出定制化的日志
|
||||
*
|
||||
*
|
||||
* 定制格式如下:01 %d{yyyy-MM-dd HH:mm:ss.SSS} %p [%-5t:%c{2}] %m%n
|
||||
* 其中:
|
||||
* 01 日志API版本,后续如果格式有变化,会修改此版本号,方便机器解析
|
||||
@ -29,17 +29,17 @@ import com.alibaba.nacos.client.logger.option.ActivateOption;
|
||||
* [%-5t:%c{2}] 线程名:日志名
|
||||
* %m 日志信息
|
||||
* %n 换行
|
||||
*
|
||||
*
|
||||
* 关于%m,也有其中的格式要求:[Context] [STAT-INFO] [ERROR-CODE]
|
||||
* 其中:
|
||||
* Context 打印时间时的上下文信息,如果没有,则内容为空,但'[]'这个占位符仍要输出
|
||||
* STAT-INFO 待定
|
||||
* ERROR-CODE 常见的错误码,帮助用户解决问题
|
||||
*
|
||||
*
|
||||
* 在异常中,也需要输出ErrorCode及对应的TraceUrl,可以使用
|
||||
* com.alibaba.nacos.client.logger.support.LoggerHelper.getErrorCodeStr(String errorCode)来获取格式化后的串
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @author zhuyong 2014年3月20日 上午9:58:27
|
||||
*/
|
||||
public interface Logger extends ActivateOption {
|
||||
@ -55,7 +55,7 @@ public interface Logger extends ActivateOption {
|
||||
* 输出Debug日志
|
||||
*
|
||||
* @param format 日志信息格式化字符串,比如 'Hi,{} {} {}'(当使用ResourceBundle用于国际化日志输出时,message为对应的key, since 0.1.5)
|
||||
* @param args 格式化串参数数组
|
||||
* @param args 格式化串参数数组
|
||||
*/
|
||||
void debug(String format, Object... args);
|
||||
|
||||
@ -71,8 +71,8 @@ public interface Logger extends ActivateOption {
|
||||
* 输出Debug日志
|
||||
*
|
||||
* @param context 日志上下文信息
|
||||
* @param format 日志信息格式化字符串,比如 'Hi,{} {} {}'(当使用ResourceBundle用于国际化日志输出时,message为对应的key, since 0.1.5)
|
||||
* @param args 格式化串参数数组
|
||||
* @param format 日志信息格式化字符串,比如 'Hi,{} {} {}'(当使用ResourceBundle用于国际化日志输出时,message为对应的key, since 0.1.5)
|
||||
* @param args 格式化串参数数组
|
||||
*/
|
||||
void debug(String context, String format, Object... args);
|
||||
|
||||
@ -87,7 +87,7 @@ public interface Logger extends ActivateOption {
|
||||
* 输出Info日志
|
||||
*
|
||||
* @param format 日志信息格式化字符串,比如 'Hi,{} {} {}'(当使用ResourceBundle用于国际化日志输出时,message为对应的key, since 0.1.5)
|
||||
* @param args 格式化串参数数组
|
||||
* @param args 格式化串参数数组
|
||||
*/
|
||||
void info(String format, Object... args);
|
||||
|
||||
@ -103,8 +103,8 @@ public interface Logger extends ActivateOption {
|
||||
* 输出Info日志
|
||||
*
|
||||
* @param context 日志上下文信息
|
||||
* @param format 日志信息格式化字符串,比如 'Hi,{} {} {}'(当使用ResourceBundle用于国际化日志输出时,message为对应的key, since 0.1.5)
|
||||
* @param args 格式化串参数数组
|
||||
* @param format 日志信息格式化字符串,比如 'Hi,{} {} {}'(当使用ResourceBundle用于国际化日志输出时,message为对应的key, since 0.1.5)
|
||||
* @param args 格式化串参数数组
|
||||
*/
|
||||
void info(String context, String format, Object... args);
|
||||
|
||||
@ -119,7 +119,7 @@ public interface Logger extends ActivateOption {
|
||||
* 输出Warn日志
|
||||
*
|
||||
* @param message 日志信息(当使用ResourceBundle用于国际化日志输出时,message为对应的key, since 0.1.5)
|
||||
* @param t 异常信息
|
||||
* @param t 异常信息
|
||||
* @since 0.1.5
|
||||
*/
|
||||
void warn(String message, Throwable t);
|
||||
@ -128,7 +128,7 @@ public interface Logger extends ActivateOption {
|
||||
* 输出Warn日志
|
||||
*
|
||||
* @param format 日志信息格式化字符串,比如 'Hi,{} {} {}'(当使用ResourceBundle用于国际化日志输出时,message为对应的key, since 0.1.5)
|
||||
* @param args 格式化串参数数组
|
||||
* @param args 格式化串参数数组
|
||||
*/
|
||||
void warn(String format, Object... args);
|
||||
|
||||
@ -144,8 +144,8 @@ public interface Logger extends ActivateOption {
|
||||
* 输出Warn日志
|
||||
*
|
||||
* @param context 日志上下文信息
|
||||
* @param format 日志信息格式化字符串,比如 'Hi,{} {} {}'(当使用ResourceBundle用于国际化日志输出时,message为对应的key, since 0.1.5)
|
||||
* @param args 格式化串参数数组
|
||||
* @param format 日志信息格式化字符串,比如 'Hi,{} {} {}'(当使用ResourceBundle用于国际化日志输出时,message为对应的key, since 0.1.5)
|
||||
* @param args 格式化串参数数组
|
||||
*/
|
||||
void warn(String context, String format, Object... args);
|
||||
|
||||
@ -153,7 +153,7 @@ public interface Logger extends ActivateOption {
|
||||
* 输出Error日志
|
||||
*
|
||||
* @param errorCode 错误码,如HSF-0001
|
||||
* @param message 日志信息(当使用ResourceBundle用于国际化日志输出时,message为对应的key, since 0.1.5)
|
||||
* @param message 日志信息(当使用ResourceBundle用于国际化日志输出时,message为对应的key, since 0.1.5)
|
||||
*/
|
||||
void error(String errorCode, String message);
|
||||
|
||||
@ -161,8 +161,8 @@ public interface Logger extends ActivateOption {
|
||||
* 输出Error日志
|
||||
*
|
||||
* @param errorCode 错误码,如HSF-0001
|
||||
* @param message 日志信息(当使用ResourceBundle用于国际化日志输出时,message为对应的key, since 0.1.5)
|
||||
* @param t 异常信息
|
||||
* @param message 日志信息(当使用ResourceBundle用于国际化日志输出时,message为对应的key, since 0.1.5)
|
||||
* @param t 异常信息
|
||||
*/
|
||||
void error(String errorCode, String message, Throwable t);
|
||||
|
||||
@ -170,68 +170,71 @@ public interface Logger extends ActivateOption {
|
||||
* 输出Error日志
|
||||
*
|
||||
* @param errorCode 错误码,如HSF-0001
|
||||
* @param format 日志信息格式化字符串,比如 'Hi,{} {} {}'(当使用ResourceBundle用于国际化日志输出时,message为对应的key, since 0.1.5)
|
||||
* @param objs 格式化串参数数组
|
||||
* @param format 日志信息格式化字符串,比如 'Hi,{} {} {}'(当使用ResourceBundle用于国际化日志输出时,message为对应的key, since 0.1.5)
|
||||
* @param objs 格式化串参数数组
|
||||
*/
|
||||
void error(String errorCode, String format, Object... objs);
|
||||
|
||||
/**
|
||||
* 输出Error日志
|
||||
*
|
||||
* @param context 日志上下文信息
|
||||
* @param context 日志上下文信息
|
||||
* @param errorCode 错误码
|
||||
* @param message 日志信息(当使用ResourceBundle用于国际化日志输出时,message为对应的key, since 0.1.5)
|
||||
* @param message 日志信息(当使用ResourceBundle用于国际化日志输出时,message为对应的key, since 0.1.5)
|
||||
*/
|
||||
void error(String context, String errorCode, String message);
|
||||
|
||||
/**
|
||||
* 输出Error日志
|
||||
*
|
||||
* @param context 日志上下文信息
|
||||
* @param context 日志上下文信息
|
||||
* @param errorCode 错误码
|
||||
* @param message 日志信息(当使用ResourceBundle用于国际化日志输出时,message为对应的key, since 0.1.5)
|
||||
* @param t 异常信息
|
||||
* @param message 日志信息(当使用ResourceBundle用于国际化日志输出时,message为对应的key, since 0.1.5)
|
||||
* @param t 异常信息
|
||||
*/
|
||||
void error(String context, String errorCode, String message, Throwable t);
|
||||
|
||||
/**
|
||||
* 输出Error日志
|
||||
*
|
||||
* @param context 日志上下文信息
|
||||
* @param context 日志上下文信息
|
||||
* @param errorCode 错误码
|
||||
* @param format 日志信息格式化字符串,比如 'Hi,{} {} {}'(当使用ResourceBundle用于国际化日志输出时,message为对应的key, since 0.1.5)
|
||||
* @param args 格式化串参数
|
||||
* @param format 日志信息格式化字符串,比如 'Hi,{} {} {}'(当使用ResourceBundle用于国际化日志输出时,message为对应的key, since 0.1.5)
|
||||
* @param args 格式化串参数
|
||||
*/
|
||||
void error(String context, String errorCode, String format, Object... args);
|
||||
|
||||
/**
|
||||
* 判断Debug级别是否开启
|
||||
*
|
||||
* @return Debug级别是否开启
|
||||
*/
|
||||
/**
|
||||
* 判断Debug级别是否开启
|
||||
*
|
||||
* @return Debug级别是否开启
|
||||
*/
|
||||
boolean isDebugEnabled();
|
||||
|
||||
/**
|
||||
* 判断Info级别是否开启
|
||||
*
|
||||
* @return Info级别是否开启
|
||||
*/
|
||||
boolean isInfoEnabled();
|
||||
|
||||
/**
|
||||
* 判断Warn级别是否开启
|
||||
*
|
||||
* @return Warn级别是否开启
|
||||
*/
|
||||
boolean isWarnEnabled();
|
||||
|
||||
/**
|
||||
* 判断Error级别是否开启
|
||||
*
|
||||
* @return Error级别是否开启
|
||||
*/
|
||||
/**
|
||||
* 判断Error级别是否开启
|
||||
*
|
||||
* @return Error级别是否开启
|
||||
*/
|
||||
boolean isErrorEnabled();
|
||||
|
||||
/**
|
||||
* * 获取内部日志实现对象
|
||||
*
|
||||
* @return 内部日志实现对象
|
||||
*/
|
||||
Object getDelegate();
|
||||
|
@ -15,16 +15,15 @@
|
||||
*/
|
||||
package com.alibaba.nacos.client.logger;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.alibaba.nacos.client.logger.log4j.Log4jLoggerFactory;
|
||||
import com.alibaba.nacos.client.logger.log4j2.Log4j2LoggerFactory;
|
||||
import com.alibaba.nacos.client.logger.nop.NopLoggerFactory;
|
||||
import com.alibaba.nacos.client.logger.slf4j.Slf4jLoggerFactory;
|
||||
import com.alibaba.nacos.client.logger.support.ILoggerFactory;
|
||||
import com.alibaba.nacos.client.logger.support.LogLog;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 阿里中间件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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,371 +28,367 @@ import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* A JSON array. JSONObject supports java.util.List interface.
|
||||
*
|
||||
* @author FangYidong<fangyidong@yahoo.com.cn>
|
||||
*
|
||||
* @author FangYidong<fangyidong @ yahoo.com.cn>
|
||||
*/
|
||||
@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();
|
||||
}
|
||||
}
|
||||
|
@ -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<fangyidong@yahoo.com.cn>
|
||||
* Beans that support customized output of JSON text shall implement this interface.
|
||||
*
|
||||
* @author FangYidong<fangyidong @ yahoo.com.cn>
|
||||
*/
|
||||
@SuppressWarnings("PMD.ClassNamingShouldBeCamelRule")
|
||||
public interface JSONAware {
|
||||
/**
|
||||
* format change
|
||||
*
|
||||
* @return JSON text
|
||||
*/
|
||||
String toJSONString();
|
||||
/**
|
||||
* format change
|
||||
*
|
||||
* @return JSON text
|
||||
*/
|
||||
String toJSONString();
|
||||
}
|
||||
|
@ -28,125 +28,118 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* A JSON object. Key value pairs are unordered. JSONObject supports java.util.Map interface.
|
||||
*
|
||||
* @author FangYidong<fangyidong@yahoo.com.cn>
|
||||
*
|
||||
* @author FangYidong<fangyidong @ yahoo.com.cn>
|
||||
*/
|
||||
@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);
|
||||
}
|
||||
}
|
||||
|
@ -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<fangyidong@yahoo.com.cn>
|
||||
* Beans that support customized output of JSON text to a writer shall implement this interface.
|
||||
*
|
||||
* @author FangYidong<fangyidong @ yahoo.com.cn>
|
||||
*/
|
||||
@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;
|
||||
}
|
||||
|
@ -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<fangyidong@yahoo.com.cn>
|
||||
* @author FangYidong<fangyidong @ yahoo.com.cn>
|
||||
*/
|
||||
@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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* DO NOT call this method from writeJSONString(Writer) of a class that implements both JSONStreamAware and (Map or List) with
|
||||
* "this" as the first parameter, use JSONObject.writeJSONString(Map, Writer) or JSONArray.writeJSONString(List, Writer) instead.
|
||||
*
|
||||
* @see com.alibaba.nacos.client.logger.jsonJSONObject#writeJSONString(Map, Writer)
|
||||
* @see com.alibaba.nacos.client.logger.jsonJSONArray#writeJSONString(List, Writer)
|
||||
*
|
||||
* DO NOT call this method from writeJSONString(Writer) of a class that implements both JSONStreamAware and (Map or
|
||||
* List) with "this" as the first parameter, use JSONObject.writeJSONString(Map, Writer) or
|
||||
* JSONArray.writeJSONString(List, Writer) instead.
|
||||
*
|
||||
* @param value
|
||||
* @param writer
|
||||
* @see com.alibaba.nacos.client.logger.jsonJSONObject#writeJSONString(Map, Writer)
|
||||
* @see com.alibaba.nacos.client.logger.jsonJSONArray#writeJSONString(List, Writer)
|
||||
*/
|
||||
public static void writeJSONString(Object value, Writer out) throws IOException {
|
||||
if(value == null){
|
||||
out.write("null");
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof String){
|
||||
out.write('\"');
|
||||
out.write(escape((String)value));
|
||||
out.write('\"');
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof Double){
|
||||
if(((Double)value).isInfinite() || ((Double)value).isNaN()) {
|
||||
out.write("null");
|
||||
}
|
||||
else {
|
||||
out.write(value.toString());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof Float){
|
||||
if(((Float)value).isInfinite() || ((Float)value).isNaN()) {
|
||||
out.write("null");
|
||||
}
|
||||
else {
|
||||
out.write(value.toString());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof Number){
|
||||
out.write(value.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof Boolean){
|
||||
out.write(value.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
if((value instanceof JSONStreamAware)){
|
||||
((JSONStreamAware)value).writeJSONString(out);
|
||||
return;
|
||||
}
|
||||
|
||||
if((value instanceof JSONAware)){
|
||||
out.write(((JSONAware)value).toJSONString());
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof Map){
|
||||
JSONObject.writeJSONString((Map)value, out);
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof Collection){
|
||||
JSONArray.writeJSONString((Collection)value, out);
|
||||
public static void writeJSONString(Object value, Writer out) throws IOException {
|
||||
if (value == null) {
|
||||
out.write("null");
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof byte[]){
|
||||
JSONArray.writeJSONString((byte[])value, out);
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof short[]){
|
||||
JSONArray.writeJSONString((short[])value, out);
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof int[]){
|
||||
JSONArray.writeJSONString((int[])value, out);
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof long[]){
|
||||
JSONArray.writeJSONString((long[])value, out);
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof float[]){
|
||||
JSONArray.writeJSONString((float[])value, out);
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof double[]){
|
||||
JSONArray.writeJSONString((double[])value, out);
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof boolean[]){
|
||||
JSONArray.writeJSONString((boolean[])value, out);
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof char[]){
|
||||
JSONArray.writeJSONString((char[])value, out);
|
||||
return;
|
||||
}
|
||||
|
||||
if(value instanceof Object[]){
|
||||
JSONArray.writeJSONString((Object[])value, out);
|
||||
return;
|
||||
}
|
||||
|
||||
out.write(value.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an object to JSON text.
|
||||
* <p>
|
||||
* If this object is a Map or a List, and it's also a JSONAware, JSONAware will be considered firstly.
|
||||
* <p>
|
||||
* DO NOT call this method from toJSONString() of a class that implements both JSONAware and Map or List with
|
||||
* "this" as the parameter, use JSONObject.toJSONString(Map) or JSONArray.toJSONString(List) instead.
|
||||
*
|
||||
* @see com.alibaba.nacos.client.logger.json.JSONObject#toJSONString(Map)
|
||||
*
|
||||
* @param value
|
||||
* @return JSON text, or "null" if value is null or it's an NaN or an INF number.
|
||||
*/
|
||||
public static String toJSONString(Object value){
|
||||
final StringWriter writer = new StringWriter();
|
||||
|
||||
try{
|
||||
writeJSONString(value, writer);
|
||||
return writer.toString();
|
||||
} catch(IOException e){
|
||||
// This should never happen for a StringWriter
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
if (value instanceof String) {
|
||||
out.write('\"');
|
||||
out.write(escape((String)value));
|
||||
out.write('\"');
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters (U+0000 through U+001F).
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public static String escape(String s){
|
||||
if(s==null) {
|
||||
return null;
|
||||
}
|
||||
if (value instanceof Double) {
|
||||
if (((Double)value).isInfinite() || ((Double)value).isNaN()) {
|
||||
out.write("null");
|
||||
} else {
|
||||
out.write(value.toString());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (value instanceof Float) {
|
||||
if (((Float)value).isInfinite() || ((Float)value).isNaN()) {
|
||||
out.write("null");
|
||||
} else {
|
||||
out.write(value.toString());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (value instanceof Number) {
|
||||
out.write(value.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (value instanceof Boolean) {
|
||||
out.write(value.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
if ((value instanceof JSONStreamAware)) {
|
||||
((JSONStreamAware)value).writeJSONString(out);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((value instanceof JSONAware)) {
|
||||
out.write(((JSONAware)value).toJSONString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (value instanceof Map) {
|
||||
JSONObject.writeJSONString((Map)value, out);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value instanceof Collection) {
|
||||
JSONArray.writeJSONString((Collection)value, out);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value instanceof byte[]) {
|
||||
JSONArray.writeJSONString((byte[])value, out);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value instanceof short[]) {
|
||||
JSONArray.writeJSONString((short[])value, out);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value instanceof int[]) {
|
||||
JSONArray.writeJSONString((int[])value, out);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value instanceof long[]) {
|
||||
JSONArray.writeJSONString((long[])value, out);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value instanceof float[]) {
|
||||
JSONArray.writeJSONString((float[])value, out);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value instanceof double[]) {
|
||||
JSONArray.writeJSONString((double[])value, out);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value instanceof boolean[]) {
|
||||
JSONArray.writeJSONString((boolean[])value, out);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value instanceof char[]) {
|
||||
JSONArray.writeJSONString((char[])value, out);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value instanceof Object[]) {
|
||||
JSONArray.writeJSONString((Object[])value, out);
|
||||
return;
|
||||
}
|
||||
|
||||
out.write(value.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an object to JSON text.
|
||||
* <p>
|
||||
* If this object is a Map or a List, and it's also a JSONAware, JSONAware will be considered firstly.
|
||||
* <p>
|
||||
* DO NOT call this method from toJSONString() of a class that implements both JSONAware and Map or List with "this"
|
||||
* as the parameter, use JSONObject.toJSONString(Map) or JSONArray.toJSONString(List) instead.
|
||||
*
|
||||
* @param value
|
||||
* @return JSON text, or "null" if value is null or it's an NaN or an INF number.
|
||||
* @see com.alibaba.nacos.client.logger.json.JSONObject#toJSONString(Map)
|
||||
*/
|
||||
public static String toJSONString(Object value) {
|
||||
final StringWriter writer = new StringWriter();
|
||||
|
||||
try {
|
||||
writeJSONString(value, writer);
|
||||
return writer.toString();
|
||||
} catch (IOException e) {
|
||||
// This should never happen for a StringWriter
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters (U+0000 through U+001F).
|
||||
*
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public static String escape(String s) {
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
StringBuffer sb = new StringBuffer();
|
||||
escape(s, sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param s - Must not be null.
|
||||
* @param s - Must not be null.
|
||||
* @param sb
|
||||
*/
|
||||
static void escape(String s, StringBuffer sb) {
|
||||
final int len = s.length();
|
||||
for(int i=0;i<len;i++){
|
||||
char ch=s.charAt(i);
|
||||
switch(ch){
|
||||
case '"':
|
||||
sb.append("\\\"");
|
||||
break;
|
||||
case '\\':
|
||||
sb.append("\\\\");
|
||||
break;
|
||||
case '\b':
|
||||
sb.append("\\b");
|
||||
break;
|
||||
case '\f':
|
||||
sb.append("\\f");
|
||||
break;
|
||||
case '\n':
|
||||
sb.append("\\n");
|
||||
break;
|
||||
case '\r':
|
||||
sb.append("\\r");
|
||||
break;
|
||||
case '\t':
|
||||
sb.append("\\t");
|
||||
break;
|
||||
case '/':
|
||||
sb.append("\\/");
|
||||
break;
|
||||
default:
|
||||
//Reference: http://www.unicode.org/versions/Unicode5.1.0/
|
||||
if(isUnicodeChar(ch)){
|
||||
String ss=Integer.toHexString(ch);
|
||||
sb.append("\\u");
|
||||
for(int k=0;k<FOUR-ss.length();k++){
|
||||
sb.append('0');
|
||||
}
|
||||
sb.append(ss.toUpperCase());
|
||||
}
|
||||
else{
|
||||
sb.append(ch);
|
||||
}
|
||||
}
|
||||
}//for
|
||||
}
|
||||
|
||||
private static boolean isUnicodeChar(char ch) {
|
||||
return (ch >= '\u0000' && ch <= '\u001F') || (ch >= '\u007F' && ch <= '\u009F')
|
||||
|| (ch >= '\u2000' && ch <= '\u20FF');
|
||||
}
|
||||
|
||||
private static int FOUR = 4;
|
||||
final int len = s.length();
|
||||
for (int i = 0; i < len; i++) {
|
||||
char ch = s.charAt(i);
|
||||
switch (ch) {
|
||||
case '"':
|
||||
sb.append("\\\"");
|
||||
break;
|
||||
case '\\':
|
||||
sb.append("\\\\");
|
||||
break;
|
||||
case '\b':
|
||||
sb.append("\\b");
|
||||
break;
|
||||
case '\f':
|
||||
sb.append("\\f");
|
||||
break;
|
||||
case '\n':
|
||||
sb.append("\\n");
|
||||
break;
|
||||
case '\r':
|
||||
sb.append("\\r");
|
||||
break;
|
||||
case '\t':
|
||||
sb.append("\\t");
|
||||
break;
|
||||
case '/':
|
||||
sb.append("\\/");
|
||||
break;
|
||||
default:
|
||||
//Reference: http://www.unicode.org/versions/Unicode5.1.0/
|
||||
if (isUnicodeChar(ch)) {
|
||||
String ss = Integer.toHexString(ch);
|
||||
sb.append("\\u");
|
||||
for (int k = 0; k < FOUR - ss.length(); k++) {
|
||||
sb.append('0');
|
||||
}
|
||||
sb.append(ss.toUpperCase());
|
||||
} else {
|
||||
sb.append(ch);
|
||||
}
|
||||
}
|
||||
}//for
|
||||
}
|
||||
|
||||
private static boolean isUnicodeChar(char ch) {
|
||||
return (ch >= '\u0000' && ch <= '\u001F') || (ch >= '\u007F' && ch <= '\u009F')
|
||||
|| (ch >= '\u2000' && ch <= '\u20FF');
|
||||
}
|
||||
|
||||
private static int FOUR = 4;
|
||||
|
||||
}
|
||||
|
@ -20,21 +20,24 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* Container factory for creating containers for JSON object and JSON array.
|
||||
*
|
||||
*
|
||||
* @author FangYidong<fangyidong @ yahoo.com.cn>
|
||||
* @see com.alibaba.nacos.client.logger.json.parser.JSONParser#parse(java.io.Reader, ContainerFactory)
|
||||
*
|
||||
* @author FangYidong<fangyidong@yahoo.com.cn>
|
||||
*/
|
||||
public interface ContainerFactory {
|
||||
/**
|
||||
* create json container
|
||||
* @return A Map instance to store JSON object, or null if you want to use com.alibaba.nacos.client.logger.jsonJSONObject.
|
||||
*/
|
||||
Map createObjectContainer();
|
||||
|
||||
/**
|
||||
* create array json container
|
||||
* @return A List instance to store JSON array, or null if you want to use com.alibaba.nacos.client.logger.jsonJSONArray.
|
||||
*/
|
||||
List creatArrayContainer();
|
||||
/**
|
||||
* create json container
|
||||
*
|
||||
* @return A Map instance to store JSON object, or null if you want to use com.alibaba.nacos.client.logger
|
||||
* .jsonJSONObject.
|
||||
*/
|
||||
Map createObjectContainer();
|
||||
|
||||
/**
|
||||
* create array json container
|
||||
*
|
||||
* @return A List instance to store JSON array, or null if you want to use com.alibaba.nacos.client.logger
|
||||
* .jsonJSONArray.
|
||||
*/
|
||||
List creatArrayContainer();
|
||||
}
|
||||
|
@ -18,112 +18,100 @@ package com.alibaba.nacos.client.logger.json.parser;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A simplified and stoppable SAX-like content handler for stream processing of JSON text.
|
||||
*
|
||||
* A simplified and stoppable SAX-like content handler for stream processing of JSON text.
|
||||
*
|
||||
* @author FangYidong<fangyidong @ yahoo.com.cn>
|
||||
* @see org.xml.sax.ContentHandler
|
||||
* @see com.alibaba.nacos.client.logger.json.parser.JSONParser#parse(java.io.Reader, ContentHandler, boolean)
|
||||
*
|
||||
* @author FangYidong<fangyidong@yahoo.com.cn>
|
||||
*/
|
||||
public interface ContentHandler {
|
||||
/**
|
||||
* Receive notification of the beginning of JSON processing.
|
||||
* The parser will invoke this method only once.
|
||||
*
|
||||
* @throws ParseException
|
||||
* - JSONParser will stop and throw the same exception to the caller when receiving this exception.
|
||||
/**
|
||||
* Receive notification of the beginning of JSON processing. The parser will invoke this method only once.
|
||||
*
|
||||
* @throws ParseException - JSONParser will stop and throw the same exception to the caller when receiving this
|
||||
* exception.
|
||||
* @throws IOException
|
||||
*/
|
||||
void startJSON() throws ParseException, IOException;
|
||||
|
||||
/**
|
||||
* Receive notification of the end of JSON processing.
|
||||
*
|
||||
* @throws ParseException
|
||||
* @throws IOException
|
||||
*/
|
||||
void endJSON() throws ParseException, IOException;
|
||||
|
||||
/**
|
||||
* Receive notification of the beginning of a JSON object.
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
* - JSONParser will stop and throw the same exception to the caller when receiving this exception.
|
||||
*/
|
||||
void startJSON() throws ParseException, IOException;
|
||||
|
||||
/**
|
||||
* Receive notification of the end of JSON processing.
|
||||
*
|
||||
* @throws ParseException
|
||||
* @throws IOException
|
||||
*/
|
||||
void endJSON() throws ParseException, IOException;
|
||||
|
||||
/**
|
||||
* Receive notification of the beginning of a JSON object.
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException - JSONParser will stop and throw the same exception to the caller when receiving this
|
||||
* exception.
|
||||
* @throws IOException
|
||||
* @see #endJSON
|
||||
*/
|
||||
boolean startObject() throws ParseException, IOException;
|
||||
|
||||
/**
|
||||
* Receive notification of the end of a JSON object.
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
* @throws IOException
|
||||
*/
|
||||
boolean startObject() throws ParseException, IOException;
|
||||
|
||||
/**
|
||||
* Receive notification of the end of a JSON object.
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
* @throws IOException
|
||||
* @see #startObject
|
||||
*/
|
||||
boolean endObject() throws ParseException, IOException;
|
||||
|
||||
/**
|
||||
* Receive notification of the beginning of a JSON object entry.
|
||||
*
|
||||
* @param key - Key of a JSON object entry.
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
* @throws IOException
|
||||
*/
|
||||
boolean endObject() throws ParseException, IOException;
|
||||
|
||||
/**
|
||||
* Receive notification of the beginning of a JSON object entry.
|
||||
*
|
||||
* @param key - Key of a JSON object entry.
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
* @throws IOException
|
||||
* @see #endObjectEntry
|
||||
*/
|
||||
boolean startObjectEntry(String key) throws ParseException, IOException;
|
||||
|
||||
/**
|
||||
* Receive notification of the end of the value of previous object entry.
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
* @throws IOException
|
||||
*/
|
||||
boolean startObjectEntry(String key) throws ParseException, IOException;
|
||||
|
||||
/**
|
||||
* Receive notification of the end of the value of previous object entry.
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
* @throws IOException
|
||||
* @see #startObjectEntry
|
||||
*/
|
||||
boolean endObjectEntry() throws ParseException, IOException;
|
||||
|
||||
/**
|
||||
* Receive notification of the beginning of a JSON array.
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
* @throws IOException
|
||||
*/
|
||||
boolean endObjectEntry() throws ParseException, IOException;
|
||||
|
||||
/**
|
||||
* Receive notification of the beginning of a JSON array.
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
* @throws IOException
|
||||
* @see #endArray
|
||||
*/
|
||||
boolean startArray() throws ParseException, IOException;
|
||||
|
||||
/**
|
||||
* Receive notification of the end of a JSON array.
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
* @throws IOException
|
||||
*/
|
||||
boolean startArray() throws ParseException, IOException;
|
||||
|
||||
/**
|
||||
* Receive notification of the end of a JSON array.
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
* @throws IOException
|
||||
* @see #startArray
|
||||
*/
|
||||
boolean endArray() throws ParseException, IOException;
|
||||
|
||||
/**
|
||||
* Receive notification of the JSON primitive values:
|
||||
* java.lang.String,
|
||||
* java.lang.Number,
|
||||
* java.lang.Boolean
|
||||
* null
|
||||
*
|
||||
* @param value - Instance of the following:
|
||||
* java.lang.String,
|
||||
* java.lang.Number,
|
||||
* java.lang.Boolean
|
||||
* null
|
||||
*
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
* @throws IOException
|
||||
*/
|
||||
boolean primitive(Object value) throws ParseException, IOException;
|
||||
|
||||
*/
|
||||
boolean endArray() throws ParseException, IOException;
|
||||
|
||||
/**
|
||||
* Receive notification of the JSON primitive values: java.lang.String, java.lang.Number, java.lang.Boolean null
|
||||
*
|
||||
* @param value - Instance of the following: java.lang.String, java.lang.Number, java.lang.Boolean null
|
||||
* @return false if the handler wants to stop parsing after return.
|
||||
* @throws ParseException
|
||||
* @throws IOException
|
||||
*/
|
||||
boolean primitive(Object value) throws ParseException, IOException;
|
||||
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -17,89 +17,87 @@ package com.alibaba.nacos.client.logger.json.parser;
|
||||
|
||||
/**
|
||||
* ParseException explains why and where the error occurs in source JSON text.
|
||||
*
|
||||
* @author FangYidong<fangyidong@yahoo.com.cn>
|
||||
*
|
||||
* @author FangYidong<fangyidong @ yahoo.com.cn>
|
||||
*/
|
||||
public class ParseException extends Exception {
|
||||
private static final long serialVersionUID = -7880698968187728547L;
|
||||
|
||||
public static final int ERROR_UNEXPECTED_CHAR = 0;
|
||||
public static final int ERROR_UNEXPECTED_TOKEN = 1;
|
||||
public static final int ERROR_UNEXPECTED_EXCEPTION = 2;
|
||||
private static final long serialVersionUID = -7880698968187728547L;
|
||||
|
||||
private int errorType;
|
||||
private Object unexpectedObject;
|
||||
private int position;
|
||||
|
||||
public ParseException(int errorType){
|
||||
this(-1, errorType, null);
|
||||
}
|
||||
|
||||
public ParseException(int errorType, Object unexpectedObject){
|
||||
this(-1, errorType, unexpectedObject);
|
||||
}
|
||||
|
||||
public ParseException(int position, int errorType, Object unexpectedObject){
|
||||
this.position = position;
|
||||
this.errorType = errorType;
|
||||
this.unexpectedObject = unexpectedObject;
|
||||
}
|
||||
|
||||
public int getErrorType() {
|
||||
return errorType;
|
||||
}
|
||||
|
||||
public void setErrorType(int errorType) {
|
||||
this.errorType = errorType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.alibaba.nacos.client.logger.json.parser.JSONParser#getPosition()
|
||||
*
|
||||
* @return The character position (starting with 0) of the input where the error occurs.
|
||||
*/
|
||||
public int getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public void setPosition(int position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.alibaba.nacos.client.logger.json.parser.Yytoken
|
||||
*
|
||||
* @return One of the following base on the value of errorType:
|
||||
* ERROR_UNEXPECTED_CHAR java.lang.Character
|
||||
* ERROR_UNEXPECTED_TOKEN com.alibaba.nacos.client.logger.jsonparser.Yytoken
|
||||
* ERROR_UNEXPECTED_EXCEPTION java.lang.Exception
|
||||
*/
|
||||
public Object getUnexpectedObject() {
|
||||
return unexpectedObject;
|
||||
}
|
||||
|
||||
public void setUnexpectedObject(Object unexpectedObject) {
|
||||
this.unexpectedObject = unexpectedObject;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
switch(errorType){
|
||||
case ERROR_UNEXPECTED_CHAR:
|
||||
sb.append("Unexpected character (").append(unexpectedObject).append(") at position ").append(position).append(".");
|
||||
break;
|
||||
case ERROR_UNEXPECTED_TOKEN:
|
||||
sb.append("Unexpected token ").append(unexpectedObject).append(" at position ").append(position).append(".");
|
||||
break;
|
||||
case ERROR_UNEXPECTED_EXCEPTION:
|
||||
sb.append("Unexpected exception at position ").append(position).append(": ").append(unexpectedObject);
|
||||
break;
|
||||
default:
|
||||
sb.append("Unkown error at position ").append(position).append(".");
|
||||
break;
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
public static final int ERROR_UNEXPECTED_CHAR = 0;
|
||||
public static final int ERROR_UNEXPECTED_TOKEN = 1;
|
||||
public static final int ERROR_UNEXPECTED_EXCEPTION = 2;
|
||||
|
||||
private int errorType;
|
||||
private Object unexpectedObject;
|
||||
private int position;
|
||||
|
||||
public ParseException(int errorType) {
|
||||
this(-1, errorType, null);
|
||||
}
|
||||
|
||||
public ParseException(int errorType, Object unexpectedObject) {
|
||||
this(-1, errorType, unexpectedObject);
|
||||
}
|
||||
|
||||
public ParseException(int position, int errorType, Object unexpectedObject) {
|
||||
this.position = position;
|
||||
this.errorType = errorType;
|
||||
this.unexpectedObject = unexpectedObject;
|
||||
}
|
||||
|
||||
public int getErrorType() {
|
||||
return errorType;
|
||||
}
|
||||
|
||||
public void setErrorType(int errorType) {
|
||||
this.errorType = errorType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The character position (starting with 0) of the input where the error occurs.
|
||||
* @see com.alibaba.nacos.client.logger.json.parser.JSONParser#getPosition()
|
||||
*/
|
||||
public int getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public void setPosition(int position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return One of the following base on the value of errorType: ERROR_UNEXPECTED_CHAR java.lang.Character
|
||||
* ERROR_UNEXPECTED_TOKEN com.alibaba.nacos.client.logger.jsonparser.Yytoken ERROR_UNEXPECTED_EXCEPTION
|
||||
* java.lang.Exception
|
||||
* @see com.alibaba.nacos.client.logger.json.parser.Yytoken
|
||||
*/
|
||||
public Object getUnexpectedObject() {
|
||||
return unexpectedObject;
|
||||
}
|
||||
|
||||
public void setUnexpectedObject(Object unexpectedObject) {
|
||||
this.unexpectedObject = unexpectedObject;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
switch (errorType) {
|
||||
case ERROR_UNEXPECTED_CHAR:
|
||||
sb.append("Unexpected character (").append(unexpectedObject).append(") at position ").append(position)
|
||||
.append(".");
|
||||
break;
|
||||
case ERROR_UNEXPECTED_TOKEN:
|
||||
sb.append("Unexpected token ").append(unexpectedObject).append(" at position ").append(position).append(
|
||||
".");
|
||||
break;
|
||||
case ERROR_UNEXPECTED_EXCEPTION:
|
||||
sb.append("Unexpected exception at position ").append(position).append(": ").append(unexpectedObject);
|
||||
break;
|
||||
default:
|
||||
sb.append("Unkown error at position ").append(position).append(".");
|
||||
break;
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
@ -23,34 +23,38 @@ import java.io.UnsupportedEncodingException;
|
||||
|
||||
/**
|
||||
* Yylex
|
||||
* @author Nacos
|
||||
*
|
||||
* @author Nacos
|
||||
*/
|
||||
class Yylex {
|
||||
|
||||
/** This character denotes the end of file */
|
||||
/**
|
||||
* This character denotes the end of file
|
||||
*/
|
||||
public static final int YYEOF = -1;
|
||||
|
||||
/** initial size of the lookahead buffer */
|
||||
/**
|
||||
* initial size of the lookahead buffer
|
||||
*/
|
||||
private static final int ZZ_BUFFERSIZE = 16384;
|
||||
|
||||
/** lexical states */
|
||||
/**
|
||||
* lexical states
|
||||
*/
|
||||
public static final int YYINITIAL = 0;
|
||||
public static final int STRING_BEGIN = 2;
|
||||
|
||||
/**
|
||||
* ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l
|
||||
* ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l
|
||||
* at the beginning of a line
|
||||
* l is of the form l = 2*k, k a non negative integer
|
||||
* ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l ZZ_LEXSTATE[l+1] is the state in the DFA for the
|
||||
* lexical state l at the beginning of a line l is of the form l = 2*k, k a non negative integer
|
||||
*/
|
||||
private static final int ZZ_LEXSTATE[] = { 0, 0, 1, 1 };
|
||||
private static final int ZZ_LEXSTATE[] = {0, 0, 1, 1};
|
||||
|
||||
/**
|
||||
* Translates characters to character classes
|
||||
*/
|
||||
private static final String ZZ_CMAP_PACKED =
|
||||
"\11\0\1\7\1\7\2\0\1\7\22\0\1\7\1\0\1\11\10\0" + "\1\6\1\31\1\2\1\4\1\12\12\3\1\32\6\0\4\1\1\5"
|
||||
"\11\0\1\7\1\7\2\0\1\7\22\0\1\7\1\0\1\11\10\0" + "\1\6\1\31\1\2\1\4\1\12\12\3\1\32\6\0\4\1\1\5"
|
||||
+ "\1\1\24\0\1\27\1\10\1\30\3\0\1\22\1\13\2\1\1\21" + "\1\14\5\0\1\23\1\0\1\15\3\0\1\16\1\24\1\17\1\20"
|
||||
+ "\5\0\1\25\1\0\1\26\uff82\0";
|
||||
|
||||
@ -65,7 +69,7 @@ class Yylex {
|
||||
private static final int[] ZZ_ACTION = zzUnpackAction();
|
||||
|
||||
private static final String ZZ_ACTION_PACKED_0 =
|
||||
"\2\0\2\1\1\2\1\3\1\4\3\1\1\5\1\6" + "\1\7\1\10\1\11\1\12\1\13\1\14\1\15\5\0"
|
||||
"\2\0\2\1\1\2\1\3\1\4\3\1\1\5\1\6" + "\1\7\1\10\1\11\1\12\1\13\1\14\1\15\5\0"
|
||||
+ "\1\14\1\16\1\17\1\20\1\21\1\22\1\23\1\24" + "\1\0\1\25\1\0\1\25\4\0\1\26\1\27\2\0" + "\1\30";
|
||||
|
||||
private static int[] zzUnpackAction() {
|
||||
@ -82,7 +86,7 @@ class Yylex {
|
||||
while (i < l) {
|
||||
int count = packed.charAt(i++);
|
||||
int value = packed.charAt(i++);
|
||||
do result[j++] = value; while (--count > 0);
|
||||
do { result[j++] = value; } while (--count > 0);
|
||||
}
|
||||
return j;
|
||||
}
|
||||
@ -93,7 +97,7 @@ class Yylex {
|
||||
private static final int[] ZZ_ROWMAP = zzUnpackRowMap();
|
||||
|
||||
private static final String ZZ_ROWMAP_PACKED_0 =
|
||||
"\0\0\0\33\0\66\0\121\0\154\0\207\0\66\0\242" + "\0\275\0\330\0\66\0\66\0\66\0\66\0\66\0\66"
|
||||
"\0\0\0\33\0\66\0\121\0\154\0\207\0\66\0\242" + "\0\275\0\330\0\66\0\66\0\66\0\66\0\66\0\66"
|
||||
+ "\0\363\0\u010e\0\66\0\u0129\0\u0144\0\u015f\0\u017a\0\u0195" + "\0\66\0\66\0\66\0\66\0\66\0\66\0\66\0\66"
|
||||
+ "\0\u01b0\0\u01cb\0\u01e6\0\u01e6\0\u0201\0\u021c\0\u0237\0\u0252" + "\0\66\0\66\0\u026d\0\u0288\0\66";
|
||||
|
||||
@ -118,42 +122,42 @@ class Yylex {
|
||||
/**
|
||||
* The transition table of the DFA
|
||||
*/
|
||||
private static final int ZZ_TRANS[] = { 2, 2, 3, 4, 2, 2, 2, 5, 2, 6, 2, 2, 7, 8, 2, 9, 2, 2, 2, 2, 2, 10, 11, 12,
|
||||
13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 17, 18, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -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, 4, -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, 4, 19, 20, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, 5, -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, 21, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 23, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16, 16, 16, 16, 16, 16, 16, 16, -1,
|
||||
-1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, 24, 25, 26, 27, 28, 29, 30, 31, 32, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, -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, 34, 35,
|
||||
-1, -1, 34, -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, 36, -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, 37, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 38, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 39, -1, 39, -1, 39, -1, -1, -1, -1,
|
||||
-1, 39, 39, -1, -1, -1, -1, 39, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, 33, -1, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, 35, -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, 38, -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, 40, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, 41, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, 42, -1, 42, -1, 42, -1, -1, -1, -1, -1, 42, 42, -1, -1, -1, -1, 42, 42,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, 43, -1, 43, -1, 43, -1, -1, -1, -1, -1,
|
||||
43, 43, -1, -1, -1, -1, 43, 43, -1, -1, -1, -1, -1, -1, -1, -1, -1, 44, -1,
|
||||
44, -1, 44, -1, -1, -1, -1, -1, 44, 44, -1, -1, -1, -1, 44, 44, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, };
|
||||
private static final int ZZ_TRANS[] = {2, 2, 3, 4, 2, 2, 2, 5, 2, 6, 2, 2, 7, 8, 2, 9, 2, 2, 2, 2, 2, 10, 11, 12,
|
||||
13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 17, 18, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -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, 4, -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, 4, 19, 20, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, 5, -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, 21, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 23, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16, 16, 16, 16, 16, 16, 16, 16, -1,
|
||||
-1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, 24, 25, 26, 27, 28, 29, 30, 31, 32, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, -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, 34, 35,
|
||||
-1, -1, 34, -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, 36, -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, 37, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 38, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 39, -1, 39, -1, 39, -1, -1, -1, -1,
|
||||
-1, 39, 39, -1, -1, -1, -1, 39, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, 33, -1, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, 35, -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, 38, -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, 40, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, 41, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, 42, -1, 42, -1, 42, -1, -1, -1, -1, -1, 42, 42, -1, -1, -1, -1, 42, 42,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, 43, -1, 43, -1, 43, -1, -1, -1, -1, -1,
|
||||
43, 43, -1, -1, -1, -1, 43, 43, -1, -1, -1, -1, -1, -1, -1, -1, -1, 44, -1,
|
||||
44, -1, 44, -1, -1, -1, -1, -1, 44, 44, -1, -1, -1, -1, 44, 44, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1,};
|
||||
|
||||
/**
|
||||
* error codes
|
||||
@ -163,10 +167,10 @@ class Yylex {
|
||||
private static final int ZZ_PUSHBACK_2BIG = 2;
|
||||
private static final int NIGTY = 90;
|
||||
/**
|
||||
* error messages for the codes above
|
||||
* error messages for the codes above
|
||||
*/
|
||||
private static final String[] ZZ_ERROR_MSG = { "Unkown internal scanner error", "Error: could not match input",
|
||||
"Error: pushback value was too large" };
|
||||
private static final String[] ZZ_ERROR_MSG = {"Unkown internal scanner error", "Error: could not match input",
|
||||
"Error: pushback value was too large"};
|
||||
|
||||
/**
|
||||
* ZZ_ATTRIBUTE[aState] contains the attributes of state <code>aState</code>
|
||||
@ -174,7 +178,7 @@ class Yylex {
|
||||
private static final int[] ZZ_ATTRIBUTE = zzUnpackAttribute();
|
||||
|
||||
private static final String ZZ_ATTRIBUTE_PACKED_0 =
|
||||
"\2\0\1\11\3\1\1\11\3\1\6\11\2\1\1\11" + "\5\0\10\11\1\0\1\1\1\0\1\1\4\0\2\11" + "\2\0\1\11";
|
||||
"\2\0\1\11\3\1\1\11\3\1\6\11\2\1\1\11" + "\5\0\10\11\1\0\1\1\1\0\1\1\4\0\2\11" + "\2\0\1\11";
|
||||
|
||||
private static int[] zzUnpackAttribute() {
|
||||
int[] result = new int[45];
|
||||
@ -185,50 +189,64 @@ class Yylex {
|
||||
|
||||
private static int zzUnpackAttribute(String packed, int offset, int[] result) {
|
||||
int i = 0;
|
||||
int j = offset;
|
||||
int j = offset;
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
int count = packed.charAt(i++);
|
||||
int value = packed.charAt(i++);
|
||||
do result[j++] = value; while (--count > 0);
|
||||
do { result[j++] = value; } while (--count > 0);
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
/** the input device */
|
||||
/**
|
||||
* the input device
|
||||
*/
|
||||
private java.io.Reader zzReader;
|
||||
|
||||
/** the current state of the DFA */
|
||||
/**
|
||||
* the current state of the DFA
|
||||
*/
|
||||
private int zzState;
|
||||
|
||||
/** the current lexical state */
|
||||
/**
|
||||
* the current lexical state
|
||||
*/
|
||||
private int zzLexicalState = YYINITIAL;
|
||||
|
||||
/**
|
||||
* this buffer contains the current text to be matched and is
|
||||
* the source of the yytext() string
|
||||
* this buffer contains the current text to be matched and is the source of the yytext() string
|
||||
*/
|
||||
private char zzBuffer[] = new char[ZZ_BUFFERSIZE];
|
||||
|
||||
/** the textposition at the last accepting state */
|
||||
/**
|
||||
* the textposition at the last accepting state
|
||||
*/
|
||||
private int zzMarkedPos;
|
||||
|
||||
/** the current text position in the buffer */
|
||||
/**
|
||||
* the current text position in the buffer
|
||||
*/
|
||||
private int zzCurrentPos;
|
||||
|
||||
/** startRead marks the beginning of the yytext() string in the buffer */
|
||||
/**
|
||||
* startRead marks the beginning of the yytext() string in the buffer
|
||||
*/
|
||||
private int zzStartRead;
|
||||
|
||||
/**
|
||||
* endRead marks the last character in the buffer, that has been read
|
||||
* from input
|
||||
* endRead marks the last character in the buffer, that has been read from input
|
||||
*/
|
||||
private int zzEndRead;
|
||||
|
||||
/** the number of characters up to the start of the matched text */
|
||||
/**
|
||||
* the number of characters up to the start of the matched text
|
||||
*/
|
||||
private int yychar;
|
||||
|
||||
/** zzAtEOF == true <=> the scanner is at the EOF */
|
||||
/**
|
||||
* zzAtEOF == true <=> the scanner is at the EOF
|
||||
*/
|
||||
private boolean zzAtEOF;
|
||||
|
||||
/**
|
||||
@ -241,8 +259,7 @@ class Yylex {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new scanner
|
||||
* There is also a java.io.InputStream version of this constructor.
|
||||
* Creates a new scanner There is also a java.io.InputStream version of this constructor.
|
||||
*
|
||||
* @param in the java.io.Reader to read input from.
|
||||
*/
|
||||
@ -251,11 +268,10 @@ class Yylex {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new scanner.
|
||||
* There is also java.io.Reader version of this constructor.
|
||||
* Creates a new scanner. There is also java.io.Reader version of this constructor.
|
||||
*
|
||||
* @param in the java.io.Inputstream to read input from.
|
||||
* @throws UnsupportedEncodingException
|
||||
* @throws UnsupportedEncodingException
|
||||
*/
|
||||
Yylex(java.io.InputStream in) throws UnsupportedEncodingException {
|
||||
this(new java.io.InputStreamReader(in, Constants.ENCODE));
|
||||
@ -269,12 +285,12 @@ class Yylex {
|
||||
*/
|
||||
private static char[] zzUnpackCMap(String packed) {
|
||||
char[] map = new char[0x10000];
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
while (i < NIGTY) {
|
||||
int count = packed.charAt(i++);
|
||||
char value = packed.charAt(i++);
|
||||
do map[j++] = value; while (--count > 0);
|
||||
do { map[j++] = value; } while (--count > 0);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
@ -287,26 +303,26 @@ class Yylex {
|
||||
*/
|
||||
private boolean zzRefill() throws java.io.IOException {
|
||||
|
||||
/* first: make room (if you can) */
|
||||
/* first: make room (if you can) */
|
||||
if (zzStartRead > 0) {
|
||||
System.arraycopy(zzBuffer, zzStartRead, zzBuffer, 0, zzEndRead - zzStartRead);
|
||||
|
||||
/* translate stored positions */
|
||||
/* translate stored positions */
|
||||
zzEndRead -= zzStartRead;
|
||||
zzCurrentPos -= zzStartRead;
|
||||
zzMarkedPos -= zzStartRead;
|
||||
zzStartRead = 0;
|
||||
}
|
||||
|
||||
/* is the buffer big enough? */
|
||||
/* is the buffer big enough? */
|
||||
if (zzCurrentPos >= zzBuffer.length) {
|
||||
/* if not: blow it up */
|
||||
/* if not: blow it up */
|
||||
char newBuffer[] = new char[zzCurrentPos * 2];
|
||||
System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length);
|
||||
zzBuffer = newBuffer;
|
||||
}
|
||||
|
||||
/* finally: fill the buffer with new input */
|
||||
/* finally: fill the buffer with new input */
|
||||
int numRead = zzReader.read(zzBuffer, zzEndRead, zzBuffer.length - zzEndRead);
|
||||
|
||||
if (numRead > 0) {
|
||||
@ -319,7 +335,7 @@ class Yylex {
|
||||
if (c == -1) {
|
||||
return true;
|
||||
} else {
|
||||
zzBuffer[zzEndRead++] = (char) c;
|
||||
zzBuffer[zzEndRead++] = (char)c;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -333,19 +349,17 @@ class Yylex {
|
||||
*/
|
||||
public final void yyclose() throws java.io.IOException {
|
||||
zzAtEOF = true;
|
||||
zzEndRead = zzStartRead;
|
||||
zzEndRead = zzStartRead;
|
||||
|
||||
if (zzReader != null) {
|
||||
zzReader.close();
|
||||
zzReader.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the scanner to read from a new input stream.
|
||||
* Does not close the old reader.
|
||||
* All internal variables are reset, the old input stream
|
||||
* <b>cannot</b> be reused (internal buffer is discarded and lost).
|
||||
* Lexical state is set to <tt>ZZ_INITIAL</tt>.
|
||||
* Resets the scanner to read from a new input stream. Does not close the old reader. All internal variables are
|
||||
* reset, the old input stream <b>cannot</b> be reused (internal buffer is discarded and lost). Lexical state is set
|
||||
* to <tt>ZZ_INITIAL</tt>.
|
||||
*
|
||||
* @param reader the new input stream
|
||||
*/
|
||||
@ -381,12 +395,10 @@ class Yylex {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the character at position <tt>pos</tt> from the
|
||||
* matched text.
|
||||
* It is equivalent to yytext().charAt(pos), but faster
|
||||
* Returns the character at position <tt>pos</tt> from the matched text. It is equivalent to yytext().charAt(pos),
|
||||
* but faster
|
||||
*
|
||||
* @param pos the position of the character to fetch.
|
||||
* A value from 0 to yylength()-1.
|
||||
* @param pos the position of the character to fetch. A value from 0 to yylength()-1.
|
||||
* @return the character at position pos
|
||||
*/
|
||||
public final char yycharat(int pos) {
|
||||
@ -401,14 +413,10 @@ class Yylex {
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports an error that occured while scanning.
|
||||
* In a wellformed scanner (no or only correct usage of
|
||||
* yypushback(int) and a match-all fallback rule) this method
|
||||
* will only be called with things that "Can't Possibly Happen".
|
||||
* If this method is called, something is seriously wrong
|
||||
* (e.g. a JFlex bug producing a faulty scanner etc.).
|
||||
* Usual syntax/scanner level error handling should be done
|
||||
* in error fallback rules.
|
||||
* Reports an error that occured while scanning. In a wellformed scanner (no or only correct usage of
|
||||
* yypushback(int) and a match-all fallback rule) this method will only be called with things that "Can't Possibly
|
||||
* Happen". If this method is called, something is seriously wrong (e.g. a JFlex bug producing a faulty scanner
|
||||
* etc.). Usual syntax/scanner level error handling should be done in error fallback rules.
|
||||
*
|
||||
* @param errorCode the code of the errormessage to display
|
||||
*/
|
||||
@ -424,23 +432,22 @@ class Yylex {
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes the specified amount of characters back into the input stream.
|
||||
* They will be read again by then next call of the scanning method
|
||||
* Pushes the specified amount of characters back into the input stream. They will be read again by then next call
|
||||
* of the scanning method
|
||||
*
|
||||
* @param number the number of characters to be read again.
|
||||
* This number must not be greater than yylength()!
|
||||
* @param number the number of characters to be read again. This number must not be greater than yylength()!
|
||||
*/
|
||||
public void yypushback(int number) {
|
||||
if (number > yylength()) {
|
||||
zzScanError(ZZ_PUSHBACK_2BIG);
|
||||
zzScanError(ZZ_PUSHBACK_2BIG);
|
||||
}
|
||||
|
||||
zzMarkedPos -= number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resumes scanning until the next regular expression is matched,
|
||||
* the end of input is encountered or an I/O-Error occurs.
|
||||
* Resumes scanning until the next regular expression is matched, the end of input is encountered or an I/O-Error
|
||||
* occurs.
|
||||
*
|
||||
* @return the next token
|
||||
* @throws java.io.IOException if any I/O-Error occurs
|
||||
@ -476,10 +483,9 @@ class Yylex {
|
||||
{
|
||||
while (true) {
|
||||
|
||||
if (zzCurrentPosL < zzEndReadL) {
|
||||
zzInput = zzBufferL[zzCurrentPosL++];
|
||||
}
|
||||
else if (zzAtEOF) {
|
||||
if (zzCurrentPosL < zzEndReadL) {
|
||||
zzInput = zzBufferL[zzCurrentPosL++];
|
||||
} else if (zzAtEOF) {
|
||||
zzInput = YYEOF;
|
||||
break zzForAction;
|
||||
} else {
|
||||
@ -500,18 +506,18 @@ class Yylex {
|
||||
}
|
||||
}
|
||||
int zzNext = zzTransL[zzRowMapL[zzState] + zzCMapL[zzInput]];
|
||||
if (zzNext == -1) {
|
||||
break zzForAction;
|
||||
}
|
||||
if (zzNext == -1) {
|
||||
break zzForAction;
|
||||
}
|
||||
zzState = zzNext;
|
||||
|
||||
int zzAttributes = zzAttrL[zzState];
|
||||
if ((zzAttributes & 1) == 1) {
|
||||
zzAction = zzState;
|
||||
zzMarkedPosL = zzCurrentPosL;
|
||||
if ((zzAttributes & 8) == 8) {
|
||||
break zzForAction;
|
||||
}
|
||||
if ((zzAttributes & 8) == 8) {
|
||||
break zzForAction;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -519,7 +525,7 @@ class Yylex {
|
||||
|
||||
// store back cached position
|
||||
zzMarkedPos = zzMarkedPosL;
|
||||
|
||||
|
||||
switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {
|
||||
case 11: {
|
||||
sb.append(yytext());
|
||||
@ -572,7 +578,8 @@ class Yylex {
|
||||
case 33:
|
||||
break;
|
||||
case 1: {
|
||||
throw new ParseException(yychar, ParseException.ERROR_UNEXPECTED_CHAR, Character.valueOf(yycharat(0)));
|
||||
throw new ParseException(yychar, ParseException.ERROR_UNEXPECTED_CHAR,
|
||||
Character.valueOf(yycharat(0)));
|
||||
}
|
||||
case 34:
|
||||
break;
|
||||
@ -614,7 +621,7 @@ class Yylex {
|
||||
case 24: {
|
||||
try {
|
||||
int ch = Integer.parseInt(yytext().substring(2), 16);
|
||||
sb.append((char) ch);
|
||||
sb.append((char)ch);
|
||||
} catch (Exception e) {
|
||||
throw new ParseException(yychar, ParseException.ERROR_UNEXPECTED_EXCEPTION, e);
|
||||
}
|
||||
|
@ -20,62 +20,62 @@
|
||||
package com.alibaba.nacos.client.logger.json.parser;
|
||||
|
||||
/**
|
||||
* @author FangYidong<fangyidong@yahoo.com.cn>
|
||||
* @author FangYidong<fangyidong @ yahoo.com.cn>
|
||||
*/
|
||||
public class Yytoken {
|
||||
/**
|
||||
* JSON primitive value: string,number,boolean,null
|
||||
*/
|
||||
public static final int TYPE_VALUE=0;
|
||||
public static final int TYPE_LEFT_BRACE=1;
|
||||
public static final int TYPE_RIGHT_BRACE=2;
|
||||
public static final int TYPE_LEFT_SQUARE=3;
|
||||
public static final int TYPE_RIGHT_SQUARE=4;
|
||||
public static final int TYPE_COMMA=5;
|
||||
public static final int TYPE_COLON=6;
|
||||
/**
|
||||
* end of file
|
||||
*/
|
||||
public static final int TYPE_EOF=-1;
|
||||
|
||||
public int type=0;
|
||||
public Object value=null;
|
||||
|
||||
public Yytoken(int type,Object value){
|
||||
this.type=type;
|
||||
this.value=value;
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
StringBuffer sb = new StringBuffer();
|
||||
switch(type){
|
||||
case TYPE_VALUE:
|
||||
sb.append("VALUE(").append(value).append(")");
|
||||
break;
|
||||
case TYPE_LEFT_BRACE:
|
||||
sb.append("LEFT BRACE({)");
|
||||
break;
|
||||
case TYPE_RIGHT_BRACE:
|
||||
sb.append("RIGHT BRACE(})");
|
||||
break;
|
||||
case TYPE_LEFT_SQUARE:
|
||||
sb.append("LEFT SQUARE([)");
|
||||
break;
|
||||
case TYPE_RIGHT_SQUARE:
|
||||
sb.append("RIGHT SQUARE(])");
|
||||
break;
|
||||
case TYPE_COMMA:
|
||||
sb.append("COMMA(,)");
|
||||
break;
|
||||
case TYPE_COLON:
|
||||
sb.append("COLON(:)");
|
||||
break;
|
||||
case TYPE_EOF:
|
||||
sb.append("END OF FILE");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
/**
|
||||
* JSON primitive value: string,number,boolean,null
|
||||
*/
|
||||
public static final int TYPE_VALUE = 0;
|
||||
public static final int TYPE_LEFT_BRACE = 1;
|
||||
public static final int TYPE_RIGHT_BRACE = 2;
|
||||
public static final int TYPE_LEFT_SQUARE = 3;
|
||||
public static final int TYPE_RIGHT_SQUARE = 4;
|
||||
public static final int TYPE_COMMA = 5;
|
||||
public static final int TYPE_COLON = 6;
|
||||
/**
|
||||
* end of file
|
||||
*/
|
||||
public static final int TYPE_EOF = -1;
|
||||
|
||||
public int type = 0;
|
||||
public Object value = null;
|
||||
|
||||
public Yytoken(int type, Object value) {
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
switch (type) {
|
||||
case TYPE_VALUE:
|
||||
sb.append("VALUE(").append(value).append(")");
|
||||
break;
|
||||
case TYPE_LEFT_BRACE:
|
||||
sb.append("LEFT BRACE({)");
|
||||
break;
|
||||
case TYPE_RIGHT_BRACE:
|
||||
sb.append("RIGHT BRACE(})");
|
||||
break;
|
||||
case TYPE_LEFT_SQUARE:
|
||||
sb.append("LEFT SQUARE([)");
|
||||
break;
|
||||
case TYPE_RIGHT_SQUARE:
|
||||
sb.append("RIGHT SQUARE(])");
|
||||
break;
|
||||
case TYPE_COMMA:
|
||||
sb.append("COMMA(,)");
|
||||
break;
|
||||
case TYPE_COLON:
|
||||
sb.append("COLON(:)");
|
||||
break;
|
||||
case TYPE_EOF:
|
||||
sb.append("END OF FILE");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
@ -1,146 +0,0 @@
|
||||
/*
|
||||
* 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.client.logger.log4j;
|
||||
|
||||
import org.apache.log4j.Level;
|
||||
|
||||
import com.alibaba.nacos.client.logger.Logger;
|
||||
import com.alibaba.nacos.client.logger.option.Log4jActivateOption;
|
||||
import com.alibaba.nacos.client.logger.support.LoggerHelper;
|
||||
import com.alibaba.nacos.client.logger.support.LoggerSupport;
|
||||
import com.alibaba.nacos.client.logger.util.MessageUtil;
|
||||
|
||||
|
||||
/**
|
||||
* Log4jLogger
|
||||
* @author Nacos
|
||||
*
|
||||
*/
|
||||
public class Log4jLogger extends LoggerSupport implements Logger {
|
||||
|
||||
private org.apache.log4j.Logger delegate;
|
||||
|
||||
public Log4jLogger(org.apache.log4j.Logger delegate) {
|
||||
super(delegate);
|
||||
|
||||
if (delegate == null) {
|
||||
throw new IllegalArgumentException("delegate Logger is null");
|
||||
}
|
||||
this.delegate = delegate;
|
||||
|
||||
this.activateOption = new Log4jActivateOption(delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(String context, String message) {
|
||||
if (isDebugEnabled()) {
|
||||
message = LoggerHelper.getResourceBundleString(getProductName(), message);
|
||||
delegate.debug(MessageUtil.getMessage(context, message));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(String context, String format, Object... args) {
|
||||
if (isDebugEnabled()) {
|
||||
format = LoggerHelper.getResourceBundleString(getProductName(), format);
|
||||
delegate.debug(MessageUtil.getMessage(context, MessageUtil.formatMessage(format, args)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String context, String message) {
|
||||
if (isInfoEnabled()) {
|
||||
message = LoggerHelper.getResourceBundleString(getProductName(), message);
|
||||
delegate.info(MessageUtil.getMessage(context, message));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String context, String format, Object... args) {
|
||||
if (isInfoEnabled()) {
|
||||
format = LoggerHelper.getResourceBundleString(getProductName(), format);
|
||||
delegate.info(MessageUtil.getMessage(context, MessageUtil.formatMessage(format, args)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String message, Throwable t) {
|
||||
if (isWarnEnabled()) {
|
||||
message = LoggerHelper.getResourceBundleString(getProductName(), message);
|
||||
delegate.warn(MessageUtil.getMessage(null, message), t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String context, String message) {
|
||||
if (isWarnEnabled()) {
|
||||
message = LoggerHelper.getResourceBundleString(getProductName(), message);
|
||||
delegate.warn(MessageUtil.getMessage(context, message));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String context, String format, Object... args) {
|
||||
if (isWarnEnabled()) {
|
||||
format = LoggerHelper.getResourceBundleString(getProductName(), format);
|
||||
delegate.warn(MessageUtil.getMessage(context, MessageUtil.formatMessage(format, args)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String context, String errorCode, String message) {
|
||||
if (isErrorEnabled()) {
|
||||
message = LoggerHelper.getResourceBundleString(getProductName(), message);
|
||||
delegate.error(MessageUtil.getMessage(context, errorCode, message));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String context, String errorCode, String message, Throwable t) {
|
||||
if (isErrorEnabled()) {
|
||||
message = LoggerHelper.getResourceBundleString(getProductName(), message);
|
||||
delegate.error(MessageUtil.getMessage(context, errorCode, message), t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String context, String errorCode, String format, Object... args) {
|
||||
if (isErrorEnabled()) {
|
||||
format = LoggerHelper.getResourceBundleString(getProductName(), format);
|
||||
delegate.error(MessageUtil.getMessage(context, errorCode, MessageUtil.formatMessage(format, args)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDebugEnabled() {
|
||||
return delegate.isDebugEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInfoEnabled() {
|
||||
return delegate.isInfoEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWarnEnabled() {
|
||||
return delegate.isEnabledFor(Level.WARN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isErrorEnabled() {
|
||||
return delegate.isEnabledFor(Level.ERROR);
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
* 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.client.logger.log4j;
|
||||
|
||||
import org.apache.log4j.LogManager;
|
||||
|
||||
import com.alibaba.nacos.client.logger.Logger;
|
||||
import com.alibaba.nacos.client.logger.nop.NopLogger;
|
||||
import com.alibaba.nacos.client.logger.support.ILoggerFactory;
|
||||
import com.alibaba.nacos.client.logger.support.LogLog;
|
||||
|
||||
/**
|
||||
* Log4jLogger Factory
|
||||
* @author Nacos
|
||||
*
|
||||
*/
|
||||
public class Log4jLoggerFactory implements ILoggerFactory {
|
||||
|
||||
public Log4jLoggerFactory() throws ClassNotFoundException {
|
||||
Class.forName("org.apache.log4j.Level");
|
||||
}
|
||||
|
||||
public Logger getLogger(Class<?> clazz) {
|
||||
try {
|
||||
return new Log4jLogger(LogManager.getLogger(clazz));
|
||||
} catch (Throwable t) {
|
||||
LogLog.error("Failed to get Log4jLogger", t);
|
||||
return new NopLogger();
|
||||
}
|
||||
}
|
||||
|
||||
public Logger getLogger(String name) {
|
||||
try {
|
||||
return new Log4jLogger(LogManager.getLogger(name));
|
||||
} catch (Throwable t) {
|
||||
LogLog.error("Failed to get Log4jLogger", t);
|
||||
return new NopLogger();
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user