chore(project): 添加项目配置文件和忽略规则

- 添加 Babel 配置文件支持 ES6+ 语法转换
- 添加 ESLint 忽略规则和配置文件
- 添加 Git 忽略规则文件
- 添加 Travis CI 配置文件
- 添加 1.4.2 版本变更日志文件
- 添加 Helm 图表辅助模板文件
- 添加 Helm 忽略规则文件
This commit is contained in:
2026-03-27 17:36:48 +08:00
commit c2453d6434
1703 changed files with 277582 additions and 0 deletions

38
.github/ISSUE_TEMPLATE/BUG_REPORT.md vendored Normal file
View File

@@ -0,0 +1,38 @@
---
name: Bug Report
about: If you would like to report a issue to Seata, please use this template.
---
- [ ] I have searched the [issues](https://github.com/seata/seata/issues) of this repository and believe that this is not a duplicate.
### . Issue Description
### Ⅱ. Describe what happened
If there is an exception, please attach the exception trace:
```
Just paste your stack trace here!
```
### Ⅲ. Describe what you expected to happen
### Ⅳ. How to reproduce it (as minimally and precisely as possible)
1. xxx
2. xxx
3. xxx
### . Anything else we need to know?
### Ⅵ. Environment:
- JDK version :
- OS :
- Others:

View File

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

17
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,17 @@
<!-- Please make sure you have read and understood the contributing guidelines -->
### . Describe what this PR did
### Ⅱ. Does this pull request fix one issue?
<!-- If that, add "fixes #xxx" below in the next line, for example, fixes #97. -->
### Ⅲ. Why don't you add test cases (unit test/integration test)?
### Ⅳ. Describe how to verify it
### . Special notes for reviews

41
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,41 @@
name: build
on:
push:
branches: [ develop,master ]
pull_request:
branches: [ develop,master ]
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
java: [8, 11]
os: [ ubuntu-18.04 ]
steps:
- uses: actions/checkout@v2
- name: Set up JDK
uses: actions/setup-java@v1
with:
java-version: ${{ matrix.java }}
- name: Set up ENV
# https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable
run: if [ "${{ matrix.java }}" == "8" ]; then
echo "IMAGE_NAME=openjdk:8u212-jre-alpine" >> $GITHUB_ENV;
elif [ "${{ matrix.java }}" == "11" ]; then
echo "IMAGE_NAME=openjdk:11-jre-stretch" >> $GITHUB_ENV;
fi
- name: Build with Maven
env:
REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
# https://docs.github.com/cn/free-pro-team@latest/actions/reference/context-and-expression-syntax-for-github-actions#github-context
run: if [ "${{github.event_name}}" == "push" ] && [ "${{github.ref}}" == "refs/heads/develop" ]; then
./mvnw clean install -DskipTests=false -Dcheckstyle.skip=false -Dlicense.skip=false -P image -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn;
else
./mvnw clean install -DskipTests=false -Dcheckstyle.skip=false -Dlicense.skip=false -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn;
fi
- name: Codecov
uses: codecov/codecov-action@v1

53
.gitignore vendored Normal file
View File

@@ -0,0 +1,53 @@
# maven ignore
target/
*.jar
*.war
*.zip
*.tar
*.tar.gz
*.class
.flattened-pom.xml
dependency-reduced-pom.xml
# eclipse ignore
.settings/
.project
.classpath
# idea ignore
.idea/
*.ipr
*.iml
*.iws
# temp ignore
*.log
*.cache
*.diff
*.patch
*.tmp
/distribution/bin/
/distribution/conf/
/distribution/lib/
/distribution/logs/
/distribution/*/bin/
/distribution/*/conf/
/distribution/*/lib/
/distribution/*/logs/
/server/*root.*
/server/.root.*
/server/sessionStore/
/server/db_store/
/sessionStore/
/test/sessionStore/
/distribution/sessionStore/
/distribution/*/sessionStore/
/file_store/
# system ignore
.DS_Store
Thumbs.db
*.orig
#h2
*.db

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

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

29
.travis.yml Normal file
View File

@@ -0,0 +1,29 @@
language: java
sudo: false # faster builds
jdk:
- openjdk11
- openjdk8
cache:
directories:
- $HOME/.m2
install: true
before_script:
- if [ "$TRAVIS_JDK_VERSION" == "openjdk8" ]; then
export IMAGE_NAME="openjdk:8u212-jre-alpine";
fi
- if [ "$TRAVIS_JDK_VERSION" == "openjdk11" ]; then
export IMAGE_NAME="openjdk:11-jre-stretch";
fi
script:
- if [ "$TRAVIS_BRANCH" == "develop" ] && [ "$TRAVIS_PULL_REQUEST" == false ]; then
travis_wait 30 ./mvnw clean install -DskipTests=false -Dcheckstyle.skip=false -Dlicense.skip=false -P image -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn;
else
travis_wait 30 ./mvnw clean install -DskipTests=false -Dcheckstyle.skip=false -Dlicense.skip=false -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn;
fi
after_success:
- bash <(curl -s https://codecov.io/bash)

11
CHANGELOG.md Normal file
View File

@@ -0,0 +1,11 @@
## 0.1.0 (Jan. 9, 2019)
#### FEATURES:
* support standalone seata-server.
* support mysql automatic transaction.
* support @GlobalTransactional spring annotation.
* support dubbo on filter.
* support mybatis ORM framework.
* support api&template.
* support dubbospringcloudmotan ect.

76
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,76 @@
# 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, sex characteristics, 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 dev-seata@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
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq

196
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,196 @@
# Contributing to Seata
It is warmly welcomed if you have interest to hack on Seata. First, we encourage this kind of willing very much. And here is a list of contributing guide for you.
## Topics
* [Reporting security issues](#reporting-security-issues)
* [Reporting general issues](#reporting-general-issues)
* [Code and doc contribution](#code-and-doc-contribution)
* [Test case contribution](#test-case-contribution)
* [Engage to help anything](#engage-to-help-anything)
* [Code Style](#code-style)
## Reporting security issues
Security issues are always treated seriously. As our usual principle, we discourage anyone to spread security issues. If you find a security issue of Seata, please do not discuss it in public and even do not open a public issue. Instead we encourage you to send us a private email to [dev-seata@googlegroups.com](mailto:dev-seata@googlegroups.com) to report this.
## Reporting general issues
To be honest, we regard every user of Seata as a very kind contributor. After experiencing Seata, you may have some feedback for the project. Then feel free to open an issue via [NEW ISSUE](https://github.com/seata/seata/issues/new/choose).
Since we collaborate project Seata in a distributed way, we appreciate **WELL-WRITTEN**, **DETAILED**, **EXPLICIT** issue reports. To make the communication more efficient, we wish everyone could search if your issue is an existing one in the searching list. If you find it existing, please add your details in comments under the existing issue instead of opening a brand new one.
To make the issue details as standard as possible, we setup an [ISSUE TEMPLATE](./.github/ISSUE_TEMPLATE) for issue reporters. Please **BE SURE** to follow the instructions to fill fields in template.
There are a lot of cases when you could open an issue:
* bug report
* feature request
* performance issues
* feature proposal
* feature design
* help wanted
* doc incomplete
* test improvement
* any questions on project
* and so on
Also we must remind that when filling a new issue, please remember to remove the sensitive data from your post. Sensitive data could be password, secret key, network locations, private business data and so on.
## Code and doc contribution
Every action to make project Seata better is encouraged. On GitHub, every improvement for Seata could be via a PR (short for pull request).
* If you find a typo, try to fix it!
* If you find a bug, try to fix it!
* If you find some redundant codes, try to remove them!
* If you find some test cases missing, try to add them!
* If you could enhance a feature, please **DO NOT** hesitate!
* If you find code implicit, try to add comments to make it clear!
* If you find code ugly, try to refactor that!
* If you can help to improve documents, it could not be better!
* If you find document incorrect, just do it and fix that!
* ...
Actually it is impossible to list them completely. Just remember one principle:
> WE ARE LOOKING FORWARD TO ANY PR FROM YOU.
Since you are ready to improve Seata with a PR, we suggest you could take a look at the PR rules here.
* [Workspace Preparation](#workspace-preparation)
* [Branch Definition](#branch-definition)
* [Commit Rules](#commit-rules)
* [PR Description](#pr-description)
### Workspace Preparation
To put forward a PR, we assume you have registered a GitHub ID. Then you could finish the preparation in the following steps:
1. **FORK** Seata to your repository. To make this work, you just need to click the button Fork in right-left of [seata/seata](https://github.com/seata/seata) main page. Then you will end up with your repository in `https://github.com/<your-username>/seata`, in which `your-username` is your GitHub username.
1. **CLONE** your own repository to develop locally. Use `git clone git@github.com:<your-username>/seata.git` to clone repository to your local machine. Then you can create new branches to finish the change you wish to make.
1. **Set Remote** upstream to be `git@github.com:seata/seata.git` using the following two commands:
```
git remote add upstream git@github.com:seata/seata.git
git remote set-url --push upstream no-pushing
```
With this remote setting, you can check your git remote configuration like this:
```
$ git remote -v
origin git@github.com:<your-username>/seata.git (fetch)
origin git@github.com:<your-username>/seata.git (push)
upstream git@github.com:seata/seata.git (fetch)
upstream no-pushing (push)
```
Adding this, we can easily synchronize local branches with upstream branches.
### Branch Definition
Right now we assume every contribution via pull request is for [branch develop](https://github.com/seata/seata/tree/develop) in Seata. Before contributing, be aware of branch definition would help a lot.
As a contributor, keep in mind again that every contribution via pull request is for branch develop. While in project Seata, there are several other branches, we generally call them release branches(such as 0.6.0,0.6.1), feature branches, hotfix branches and master branch.
When officially releasing a version, there will be a release branch and named with the version number.
After the release, we will merge the commit of the release branch into the master branch.
When we find that there is a bug in a certain version, we will decide to fix it in a later version or fix it in a specific hotfix version. When we decide to fix the hotfix version, we will checkout the hotfix branch based on the corresponding release branch, perform code repair and verification, and merge it into the develop branch and the master branch.
For larger features, we will pull out the feature branch for development and verification.
### Commit Rules
Actually in Seata, we take two rules serious when committing:
* [Commit Message](#commit-message)
* [Commit Content](#commit-content)
#### Commit Message
Commit message could help reviewers better understand what is the purpose of submitted PR. It could help accelerate the code review procedure as well. We encourage contributors to use **EXPLICIT** commit message rather than ambiguous message. In general, we advocate the following commit message type:
* docs: xxxx. For example, "docs: add docs about Seata cluster installation".
* feature: xxxx.For example, "feature: support oracle in AT mode".
* bugfix: xxxx. For example, "bugfix: fix panic when input nil parameter".
* refactor: xxxx. For example, "refactor: simplify to make codes more readable".
* test: xxx. For example, "test: add unit test case for func InsertIntoArray".
* other readable and explicit expression ways.
On the other side, we discourage contributors from committing message like the following ways:
* ~~fix bug~~
* ~~update~~
* ~~add doc~~
If you get lost, please see [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/) for a start.
#### Commit Content
Commit content represents all content changes included in one commit. We had better include things in one single commit which could support reviewer's complete review without any other commits' help. In another word, contents in one single commit can pass the CI to avoid code mess. In brief, there are three minor rules for us to keep in mind:
* avoid very large change in a commit;
* complete and reviewable for each commit.
* check git config(`user.name`, `user.email`) when committing to ensure that it is associated with your github ID.
* when submitting pr, please add a brief description of the current changes to the X.X.X.md file under the 'changes/' folder
In addition, in the code change part, we suggest that all contributors should read the [code style of Seata](#code-style).
No matter commit message, or commit content, we do take more emphasis on code review.
### PR Description
PR is the only way to make change to Seata project files. To help reviewers better get your purpose, PR description could not be too detailed. We encourage contributors to follow the [PR template](./.github/PULL_REQUEST_TEMPLATE.md) to finish the pull request.
## Test case contribution
Any test case would be welcomed. Currently, Seata function test cases are high priority.
* For unit test, you need to create a test file named `xxxTest.java` in the test directory of the same module. Recommend you to use the junit5 UT framework
* For integration test, you can put the integration test in the test directory or the seata-test module. It is recommended to use the mockito test framework.
## Engage to help anything
We choose GitHub as the primary place for Seata to collaborate. So the latest updates of Seata are always here. Although contributions via PR is an explicit way to help, we still call for any other ways.
* reply to other's issues if you could;
* help solve other user's problems;
* help review other's PR design;
* help review other's codes in PR;
* discuss about Seata to make things clearer;
* advocate Seata technology beyond GitHub;
* write blogs on Seata and so on.
## Code Style
Seata code style Comply with Alibaba Java Coding Guidelines.
### Guidelines
[Alibaba-Java-Coding-Guidelines](https://alibaba.github.io/Alibaba-Java-Coding-Guidelines/)
### IDE Plugin Installnot necessary
*It is not necessary to install, if you want to find a problem when you are coding.*
#### idea IDE
[p3c-idea-plugin-install](https://github.com/alibaba/p3c/blob/master/idea-plugin/README.md)
#### eclipse IDE
[p3c-eclipse-plugin-install](https://github.com/alibaba/p3c/blob/master/eclipse-plugin/README.md)
In a word, **ANY HELP IS CONTRIBUTION.**

201
LICENSE Normal file
View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (properties) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.

0
NOTICE.md Normal file
View File

294
README.md Normal file
View File

@@ -0,0 +1,294 @@
<img src="https://img.alicdn.com/imgextra/i1/O1CN011z0JfQ2723QgDiWuH_!!6000000007738-2-tps-1497-401.png" height="100" width="426">
# Seata: Simple Extensible Autonomous Transaction Architecture
[![Build Status](https://github.com/seata/seata/workflows/build/badge.svg?branch=develop)](https://github.com/seata/seata/actions)
[![codecov](https://codecov.io/gh/seata/seata/branch/develop/graph/badge.svg)](https://codecov.io/gh/seata/seata)
[![license](https://img.shields.io/github/license/seata/seata.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
[![maven](https://img.shields.io/maven-central/v/io.seata/seata-parent.svg)](https://search.maven.org/search?q=io.seata)
[![](https://img.shields.io/twitter/follow/seataio.svg?label=Follow&style=social&logoWidth=0)](https://twitter.com/intent/follow?screen_name=seataio)
## What is Seata?
A **distributed transaction solution** with high performance and ease of use for **microservices** architecture.
### Distributed Transaction Problem in Microservices
Let's imagine a traditional monolithic application. Its business is built up with 3 modules. They use a single local data source.
Naturally, data consistency will be guaranteed by the local transaction.
![Monolithic App](https://cdn.nlark.com/lark/0/2018/png/18862/1545296770244-4cedf37e-9dc6-4fc0-a97f-f4240b9d8640.png)
Things have changed in a microservices architecture. The 3 modules mentioned above are designed to be 3 services on top of 3 different data sources ([Pattern: Database per service](http://microservices.io/patterns/data/database-per-service.html)). Data consistency within every single service is naturally guaranteed by the local transaction.
**But how about the whole business logic scope?**
![Microservices Problem](https://cdn.nlark.com/lark/0/2018/png/18862/1545296781231-4029da9c-8803-43a4-ac2f-6c8b1e2ea448.png)
### How Seata do?
Seata is just a solution to the problem mentioned above.
![Seata solution](https://cdn.nlark.com/lark/0/2018/png/18862/1545296791074-3bce7bce-025e-45c3-9386-7b95135dade8.png)
Firstly, how to define a **Distributed Transaction**?
We say, a **Distributed Transaction** is a **Global Transaction** which is made up with a batch of **Branch Transaction**, and normally **Branch Transaction** is just **Local Transaction**.
![Global & Branch](https://cdn.nlark.com/lark/0/2018/png/18862/1545015454979-a18e16f6-ed41-44f1-9c7a-bd82c4d5ff99.png)
There are 3 basic components in Seata:
- **Transaction Coordinator(TC):** Maintain status of global and branch transactions, drive the global commit or rollback.
- **Transaction Manager(TM):** Define the scope of global transaction: begin a global transaction, commit or rollback a global transaction.
- **Resource Manager(RM):** Manage resources that branch transactions working on, talk to TC for registering branch transactions and reporting status of branch transactions, and drive the branch transaction commit or rollback.
![Model](https://cdn.nlark.com/lark/0/2018/png/18862/1545013915286-4a90f0df-5fda-41e1-91e0-2aa3d331c035.png)
A typical lifecycle of Seata managed distributed transaction:
1. TM asks TC to begin a new global transaction. TC generates an XID representing the global transaction.
2. XID is propagated through microservices' invoke chain.
3. RM registers local transaction as a branch of the corresponding global transaction of XID to TC.
4. TM asks TC for committing or rollbacking the corresponding global transaction of XID.
5. TC drives all branch transactions under the corresponding global transaction of XID to finish branch committing or rollbacking.
![Typical Process](https://cdn.nlark.com/lark/0/2018/png/18862/1545296917881-26fabeb9-71fa-4f3e-8a7a-fc317d3389f4.png)
For more details about principle and design, please go to [Seata wiki page](https://github.com/seata/seata/wiki).
### History
##### Ant Financial
- **XTS**: Extended Transaction Service. Ant Financial middleware team developed the distributed transaction middleware since 2007, which is widely used in Ant Financial and solves the problems of data consistency across databases and services.
- **DTX**: Distributed Transaction Extended. Since 2013, XTS has been published on the Ant Financial Cloud, with the name of DTX .
##### Alibaba
- **TXC**: Taobao Transaction Constructor. Alibaba middleware team started this project since 2014 to meet the distributed transaction problems caused by application architecture change from monolithic to microservices.
- **GTS**: Global Transaction Service. TXC as an Aliyun middleware product with new name GTS was published since 2016.
- **Fescar**: we started the open source project Fescar based on TXC/GTS since 2019 to work closely with the community in the future.
##### Seata Community
- **Seata** :Simple Extensible Autonomous Transaction Architecture. Ant Financial joins Fescar, which make it to be a more neutral and open community for distributed transaction, and Fescar be renamed to Seata.
## Maven dependency
```xml
<seata.version>1.4.2</seata.version>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
<version>${seata.version}</version>
</dependency>
```
## Quick Start
[Quick Start](https://github.com/seata/seata/wiki/Quick-Start)
## Documentation
You can view the full documentation from the wiki: [Seata wiki page](https://github.com/seata/seata/wiki).
## Reporting bugs
Please follow the [template](https://github.com/seata/seata/blob/develop/.github/ISSUE_TEMPLATE/BUG_REPORT.md) for reporting any issues.
## Contributing
Contributors are welcomed to join the Seata project. Please check [CONTRIBUTING](./CONTRIBUTING.md) about how to contribute to this project.
## Contact
* [Twitter](https://twitter.com/seataio): Follow along for latest Seata news on Twitter.
* Mailing list:
* dev-seata@googlegroups.com , for dev/user discussion. [subscribe](mailto:dev-seata+subscribe@googlegroups.com), [unsubscribe](mailto:dev-seata+unsubscribe@googlegroups.com), [archive](https://groups.google.com/forum/#!forum/dev-seata)
<img src="https://img.alicdn.com/imgextra/i3/O1CN01FKBxyk25Ffx83dIJc_!!6000000007497-0-tps-1078-354.jpg" height="200" width="630">
## Seata ecosystem
* [Seata Ecosystem Entry](https://github.com/seata) - A GitHub group `seata` to gather all Seata relevant projects
* [Seata GoLang](https://github.com/opentrx/seata-golang) - Seata GoLang client and server
* [Seata Samples](https://github.com/seata/seata-samples) - Samples for Seata
* [Seata Docker](https://github.com/seata/seata-docker) - Seata integration with docker
* [Seata K8s](https://github.com/seata/seata-k8s) - Seata integration with k8s
* [Awesome Seata](https://github.com/seata/awesome-seata) - Seata's slides and video address in meetup
* [Seata Website](https://github.com/seata/seata.github.io) - Seata official website
## Contributors
This project exists thanks to all the people who contribute. [[Contributors](https://github.com/seata/seata/graphs/contributors)].
## License
Seata is under the Apache 2.0 license. See the [LICENSE](https://github.com/seata/seata/blob/master/LICENSE) file for details.
## Who is using
These are only part of the companies using Seata, for reference only. If you are using Seata, please [add your company
here](https://github.com/seata/seata/issues/1246) to tell us your scenario to make Seata better.
<div style='vertical-align: middle'>
<img alt='Alibaba Group' height='40' src='https://docs.alibabagroup.com/assets2/images/en/global/logo_header.png' /img>
<img alt='蚂蚁金服' height='40' src='https://img.alicdn.com/tfs/TB1wuuCoET1gK0jSZFhXXaAtVXa-496-202.jpg' /img>
<img alt='阿里云' height='40' src='https://img.alicdn.com/tfs/TB1Ly5oS3HqK1RjSZFPXXcwapXa-238-54.png' /img>
<img alt='中航信' height='40' src='https://www.travelskyir.com/img/logo.gif' /img>
<img alt='联通(浙江)' height='40' src='https://img.alicdn.com/tfs/TB1hvabw9f2gK0jSZFPXXXsopXa-174-100.png' /img>
<img alt='中国铁塔' height='40' src='https://www.china-tower.com/static/web/images/tower-logo.png' /img>
<img alt='滴滴' height='40' src='https://website.didiglobal.com/dist/media/logo-zh.a7abd90d.svg' /img>
<img alt='中国邮政' height='40' src='http://www.chinapost.com.cn/res/chinapostplan/structure/181041269.png' /img>
<img alt='58集团' height='40' src='http://img.58cdn.com.cn/logo/58/252_84/logo-o.png?v=2' /img>
<img alt='南航' height='40' src='https://img.alicdn.com/tfs/TB1GMQpZHY1gK0jSZTEXXXDQVXa-203-63.png' /img>
<img alt='TCL' height='40' src='https://img.alicdn.com/tfs/TB1oHThw.Y1gK0jSZFCXXcwqXXa-214-200.png' /img>
<img alt='韵达快递' height='40' src='http://www.yunda56.com/cn/images/ky_images/logo.png' /img>
<img alt='科大讯飞' height='40' src='https://img.alicdn.com/tfs/TB1x0p5jxvbeK8jSZPfXXariXXa-272-83.png' /img>
<img alt='奇虎360' height='40' src='https://img.alicdn.com/imgextra/i2/O1CN01M9aSuY1nQWGxoVQu9_!!6000000005084-2-tps-239-78.png' /img>
<img alt='收钱吧' height='40' src='https://img.alicdn.com/imgextra/i1/O1CN01PmTFnO1gZ2K7GUpgh_!!6000000004155-2-tps-2406-747.png' /img>
<img alt='太极计算机' height='40' src='https://img.alicdn.com/tfs/TB1.zqEoAL0gK0jSZFAXXcA9pXa-245-38.png' /img>
<img alt='美的集团' height='40' src='https://img.alicdn.com/tfs/TB1cgvjwYj1gK0jSZFOXXc7GpXa-1040-282.png' /img>
<img alt='中国网安' height='40' src='https://img.alicdn.com/imgextra/i3/O1CN01OioqXX1dfxSxg6DYn_!!6000000003764-2-tps-574-122.png' /img>
<img alt='政采云' height='40' src='https://img.alicdn.com/tfs/TB1DDiCorY1gK0jSZTEXXXDQVXa-440-114.jpg' /img>
<img alt='浙江公安厅' height='40' src='https://img.alicdn.com/tfs/TB1SXGzoxn1gK0jSZKPXXXvUXXa-426-180.jpg' /img>
<img alt='特步' height='40' src='https://www.xtep.com/public/images/logo.png' /img>
<img alt='中通快递' height='40' src='https://img.alicdn.com/tfs/TB1rCNSFxn1gK0jSZKPXXXvUXXa-172-31.png' /img>
<img alt='欧莱雅百库' height='40' src='https://img.alicdn.com/tfs/TB1Xa3bZQL0gK0jSZFtXXXQCXXa-936-93.png' /img>
<img alt='浙江烟草' height='40' src='https://img.alicdn.com/tfs/TB1e7Wiovb2gK0jSZK9XXaEgFXa-1028-160.jpg' /img>
<img alt='波司登' height='40' src='https://img.alicdn.com/tfs/TB12cmCouL2gK0jSZFmXXc7iXXa-310-110.jpg' /img>
<img alt='凯京科技' height='40' src='https://img.alicdn.com/tfs/TB1j0dEop67gK0jSZPfXXahhFXa-400-208.jpg' /img>
<img alt='点购集团' height='40' src='https://dgmall-1258058953.cos.ap-chengdu.myqcloud.com/img/logo_t.png' /img>
<img alt='求是创新健康' height='40' src='http://www.truthai.cn/static/logo800.png' /img>
<img alt='科蓝' height='40' src='https://img.alicdn.com/tfs/TB1tuSyouT2gK0jSZFvXXXnFXXa-304-94.jpg' /img>
<img alt='康美药业' height='40' src='http://www.kangmei.com.cn/statics/images/kangmei/logo.png' /img>
<img alt='雁联' height='40' src='https://img.alicdn.com/tfs/TB1c8iCouL2gK0jSZFmXXc7iXXa-428-102.jpg' /img>
<img alt='学两手' height='40' src='https://img.xue2shou.com/g-xue2shou/website/0.8.2/static/logo.png' /img>
<img alt='衣二三' height='40' src='https://img.alicdn.com/tfs/TB1OCGioCf2gK0jSZFPXXXsopXa-500-179.jpg' /img>
<img alt='北京薪福社' height='40' src='https://img.alicdn.com/tfs/TB1Atu9ovzO3e4jSZFxXXaP_FXa-310-60.png' /img>
<img alt='叩丁狼教育' height='40' src='https://img.alicdn.com/tfs/TB1pfYTpRBh1e4jSZFhXXcC9VXa-151-72.png' /img>
<img alt='悦途出行' height='40' src='http://yuetu365.com/uploads/allimg/20191016/d456dbbee0c54274a70d588af4ce6116.png' /img>
<img alt='国信易企签' height='40' src='https://img.alicdn.com/tfs/TB1UTwmZFT7gK0jSZFpXXaTkpXa-201-85.png' /img>
<img alt='睿颐软件' height='40' src='https://img.alicdn.com/tfs/TB143R4op67gK0jSZPfXXahhFXa-148-42.png' /img>
<img alt='全房通' height='40' src='https://img.alicdn.com/tfs/TB1iMSAopP7gK0jSZFjXXc5aXXa-398-182.jpg' /img>
<img alt='有利网' height='40' src='https://www.yooli.com/v2/local/img/common/logo.png?version=20191126190304' /img>
<img alt='赛维' height='40' src='http://www.savor.com.cn/common/img/logo.png' /img>
<img alt='安心保险' height='40' src='https://www.95303.com/img/header/logo_header.png' /img>
<img alt='科达科技' height='40' src='https://img.alicdn.com/tfs/TB1JvOjouT2gK0jSZFvXXXnFXXa-386-146.jpg' /img>
<img alt='会分期' height='40' src='https://img.alicdn.com/tfs/TB1ChKFoBr0gK0jSZFnXXbRRXXa-402-166.jpg' /img>
<img alt='会找房' height='40' src='https://img.alicdn.com/tfs/TB1bNWFoBr0gK0jSZFnXXbRRXXa-398-336.jpg' /img>
<img alt='会通教育' height='40' src='https://img.alicdn.com/tfs/TB1_D9Boxn1gK0jSZKPXXXvUXXa-580-218.jpg' /img>
<img alt='享住智慧' height='40' src='http://image.xiangzhuzhihui.com/images/logo/logo_02.png' /img>
<img alt='兰亮网络' height='40' src='https://img.alicdn.com/tfs/TB1_miroq61gK0jSZFlXXXDKFXa-283-70.png' /img>
<img alt='桔子数科' height='40' src='https://img.alicdn.com/tfs/TB1HD.oZUY1gK0jSZFMXXaWcVXa-300-300.png' /img>
<img alt='蓝天教育' height='40' src='https://img.alicdn.com/tfs/TB1CaSroAT2gK0jSZPcXXcKkpXa-492-176.jpg' /img>
<img alt='烟台欣合' height='40' src='https://shinhoglobal.com/img/logo-shinho.svg' /img>
<img alt='阿康健康' height='40' src='https://img.alicdn.com/tfs/TB1JNSqouH2gK0jSZFEXXcqMpXa-450-182.jpg' /img>
<img alt='财新传媒' height='40' src='http://file.caixin.com/file/content/images/new/logo_bottom.png' /img>
<img alt='新脉远' height='40' src='https://img.alicdn.com/tfs/TB1NV1uouH2gK0jSZJnXXaT1FXa-462-172.jpg' /img>
<img alt='乾动新能源' height='40' src='http://www.cangowin.com/images/logo.png' /img>
<img alt='路客精品民宿' height='40' src='https://img.alicdn.com/tfs/TB1CCavoBr0gK0jSZFnXXbRRXXa-240-100.png' /img>
<img alt='深圳好尔美' height='40' src='https://img.alicdn.com/tfs/TB1IIivoxD1gK0jSZFyXXciOVXa-200-130.png' /img>
<img alt='浙大睿医' height='40' src='https://img.alicdn.com/tfs/TB1kQThrFY7gK0jSZKzXXaikpXa-220-110.jpg' /img>
<img alt='深圳市云羿贸易科技有限公司' height='40' src='https://img.alicdn.com/tfs/TB15r7dZHY1gK0jSZTEXXXDQVXa-234-233.png' /img>
<img alt='居然之家' height='40' src='https://img.alicdn.com/tfs/TB1LK6jrUT1gK0jSZFrXXcNCXXa-180-54.png' /img>
<img alt='深圳来电科技有限公司' height='40' src='https://img.alicdn.com/tfs/TB1SEzM0eL2gK0jSZFmXXc7iXXa-154-45.png' /img>
<img alt='臻善科技' height='40' src='http://www.gisquest.com/static/web/img/img-1.png?v=v3' /img>
<img alt='中国支付通' height='40' src='https://img.alicdn.com/tfs/TB1VGpTFET1gK0jSZFrXXcNCXXa-193-55.png' /img>
<img alt='众网小贷' height='40' src='https://img.alicdn.com/tfs/TB19Y8XFEY1gK0jSZFMXXaWcVXa-160-60.png' /img>
<img alt='谐云科技' height='40' src='https://img.alicdn.com/tfs/TB1V1YlrRv0gK0jSZKbXXbK2FXa-514-160.png' /img>
<img alt='浙江甄品' height='40' src='https://img.alicdn.com/tfs/TB1oC2prND1gK0jSZFyXXciOVXa-246-124.jpg' /img>
<img alt='深圳海豚网' height='40' src='https://img.alicdn.com/tfs/TB1defkrLb2gK0jSZK9XXaEgFXa-434-146.jpg' /img>
<img alt='汇通天下' height='40' src='https://img.alicdn.com/tfs/TB1uIHmrHr1gK0jSZR0XXbP8XXa-1024-568.png' /img>
<img alt='九机网' height='40' src='https://img.alicdn.com/tfs/TB1ERHlrUY1gK0jSZFMXXaWcVXa-120-60.png' /img>
<img alt='有好东西' height='40' src='https://img.alicdn.com/tfs/TB1LT2lrNn1gK0jSZKPXXXvUXXa-300-300.jpg' /img>
<img alt='南京智慧盾' height='40' src='https://img.alicdn.com/tfs/TB1s2LprUY1gK0jSZFCXXcwqXXa-618-148.jpg' /img>
<img alt='数跑科技' height='40' src='https://img.alicdn.com/tfs/TB1qtGew7T2gK0jSZPcXXcKkpXa-294-104.png' /img>
<img alt='拉粉粉' height='40' src='https://www.lafenfen.cn/img/icon03.png' /img>
<img alt='汇通达' height='40' src='https://img.alicdn.com/tfs/TB1KVJ9wWL7gK0jSZFBXXXZZpXa-145-59.png' /img>
<img alt='易宝支付' height='40' src='https://img.alicdn.com/tfs/TB1vWafw7T2gK0jSZFkXXcIQFXa-301-100.png' /img>
<img alt='维恩贝特' height='40' src='http://www.vivebest.com/templates/crs/images/vnb_logo.png' /img>
<img alt='八库' height='40' src='https://img.alicdn.com/tfs/TB1hC5cwVY7gK0jSZKzXXaikpXa-318-134.png' /img>
<img alt='大诚若谷' height='40' src='https://img.alicdn.com/tfs/TB1VuPhw4D1gK0jSZFyXXciOVXa-294-124.png' /img>
<img alt='杭州华网信息' height='40' src='https://img.alicdn.com/tfs/TB1FFX6FqL7gK0jSZFBXXXZZpXa-288-101.png' /img>
<img alt='深圳易佰' height='40' src='https://img.alicdn.com/tfs/TB1gkXaFrr1gK0jSZR0XXbP8XXa-187-57.png' /img>
<img alt='易点生活' height='40' src='https://img.alicdn.com/imgextra/i3/O1CN01svojxj1LuvK3hgQ5Y_!!6000000001360-2-tps-133-48.png' /img>
<img alt='成都数智索' height='40' src='https://img.alicdn.com/tfs/TB1oJKiw4D1gK0jSZFyXXciOVXa-2053-377.png' /img>
<img alt='北京超图' height='40' src='https://img.alicdn.com/tfs/TB1eKFXFEz1gK0jSZLeXXb9kVXa-163-54.png' /img>
<img alt='江西群享科技有限公司' height='40' src='https://img.alicdn.com/tfs/TB1Qcd0p79l0K4jSZFKXXXFjpXa-372-125.png' /img>
<img alt='宋城独木桥网络有限公司' height='40' src='https://img.alicdn.com/tfs/TB1UKocmPMZ7e4jSZFOXXX7epXa-234-82.png' /img>
<img alt='唯小宝(江苏)网络技术有限公司' height='40' src='https://img.alicdn.com/tfs/TB1eswAZFP7gK0jSZFjXXc5aXXa-800-800.png' /img>
<img alt='杭州喜团科技' height='40' src='https://img.alicdn.com/tfs/TB1IXqgwYj1gK0jSZFuXXcrHpXa-197-58.png' /img>
<img alt='海典软件' height='40' src='https://img.alicdn.com/tfs/TB1KmosZNv1gK0jSZFFXXb0sXXa-247-61.png' /img>
<img alt='中元健康科技有限公司' height='40' src='https://img.alicdn.com/imgextra/i3/O1CN018aBoRi1ZOm8uiOJwA_!!6000000003185-0-tps-1659-569.jpg' /img>
<img alt='宿迁民丰农商银行' height='40' src='https://img.alicdn.com/tfs/TB1bH5fw7L0gK0jSZFAXXcA9pXa-442-39.png' /img>
<img alt='上海海智在线' height='40' src='https://img.alicdn.com/tfs/TB1xAJUFy_1gK0jSZFqXXcpaXXa-320-80.jpg' /img>
<img alt='丞家(上海)公寓管理' height='40' src='https://image.cjia.com/website/apartment/webresource/image/logo_8f2f47fe.png' /img>
<img alt='安徽国科新材科' height='40' src='https://img.alicdn.com/tfs/TB1ICJfFuH2gK0jSZJnXXaT1FXa-654-232.png' /img>
<img alt='商银信支付' height='40' src='https://img.alicdn.com/tfs/TB1rxndw4n1gK0jSZKPXXXvUXXa-150-68.png' /img>
<img alt='钛师傅云' height='40' src='https://www.tsfyun.com/images/logo.png' /img>
<img alt='广州力生信息' height='40' src='https://img.alicdn.com/tfs/TB1m0FcFuH2gK0jSZFEXXcqMpXa-139-48.png' /img>
<img alt='杭州启舰科技有限公司' height='40' src='http://www.qijian-tech.com/img/logo.33134af4.png' /img>
<img alt='微链' height='40' src='https://img.alicdn.com/tfs/TB14LhHmMgP7K4jSZFqXXamhVXa-300-135.png' /img>
<img alt='上海美浮特' height='40' src='https://img.alicdn.com/tfs/TB1uUtaFuT2gK0jSZFvXXXnFXXa-370-45.jpg' /img>
<img alt='江西群享科技有限公司' height='40' src='https://img.alicdn.com/imgextra/i3/O1CN018AiGbE1PZdN8Vu4Fd_!!6000000001855-2-tps-630-220.png' /img>
<img alt='杭州中威慧云医疗科技有限公司' height='40' src='https://img.alicdn.com/tfs/TB1iqo_FaL7gK0jSZFBXXXZZpXa-361-54.jpg' /img>
<img alt='易族智汇(北京)' height='40' src='http://www.javamall.com.cn/images/logonew.jpg' /img>
<img alt='佛山宅无限' height='40' src='https://zwxnetwork.oss-cn-shenzhen.aliyuncs.com/static/temporary_official_website/logo.png' /img>
<img alt='F5未来商店' height='40' src='https://cdn.f5-store.cn/front_end/common_images/logo.png' /img>
<img alt='重庆雷高科技有限公司' height='40' src='https://img.alicdn.com/imgextra/i3/O1CN01TKiMMC1VQpSIe3n7i_!!6000000002648-2-tps-931-865.png' /img>
<img alt='甄品信息科技' height='40' src='https://img.alicdn.com/tfs/TB1SxJWFEY1gK0jSZFCXXcwqXXa-185-65.png' /img>
<img alt='行云全球汇跨境电商(杭州分部)' height='40' src='http://www.xyb2b.com/_nuxt/img/5e5584f.png' /img>
<img alt='世纪加华' height='40' src='https://zhengxin-pub.bj.bcebos.com/logopic/a4ff4990e2ba2d57c90e8d16c649b952_fullsize.jpg?x-bce-process=image/resize,m_lfit,w_200' /img>
<img alt='快陪练' height='40' src='https://img.alicdn.com/tfs/TB1rhNRFAL0gK0jSZFtXXXQCXXa-321-96.png' /img>
<img alt='西南石油大学' height='40' src='https://dss2.bdstatic.com/6Ot1bjeh1BF3odCf/it/u=829617221,290823158&fm=74&app=80&f=JPEG&size=f121,121?sec=1880279984&t=b0b603710dd0af061a278d11cfe327ae' /img>
<img alt='厦门服云信息科技有限公司' height='40' src='https://img.alicdn.com/tfs/TB1zuAzZKL2gK0jSZFmXXc7iXXa-691-263.png' /img>
<img alt='领课网络' height='40' src='https://img.alicdn.com/tfs/TB18TNRFEz1gK0jSZLeXXb9kVXa-244-60.jpg' /img>
<img alt='美通社' height='40' src='https://img.alicdn.com/tfs/TB1i1JTFCf2gK0jSZFPXXXsopXa-151-60.png' /img>
<img alt='睿维科技有限公司' height='40' src='https://img.alicdn.com/tfs/TB1ztXXFpY7gK0jSZKzXXaikpXa-179-60.png' /img>
<img alt='郑州信源信息技术' height='40' src='https://img.alicdn.com/tfs/TB1SkJ9FuT2gK0jSZFvXXXnFXXa-266-56.png' /img>
<img alt='荣怀集团' height='40' src='https://img.alicdn.com/tfs/TB1AzbWgZKfxu4jSZPfXXb3dXXa-1117-382.png' /img>
<img alt='浙江群集大数据科技有限公司' height='40' src='https://img.alicdn.com/tfs/TB1HtFZFq61gK0jSZFlXXXDKFXa-1375-214.png' /img>
<img alt='北京易点租有限公司' height='40' src='https://img.alicdn.com/tfs/TB1nax.FuH2gK0jSZFEXXcqMpXa-336-154.png' /img>
<img alt='浙江蕙康科技有限公司' height='40' src='https://img.alicdn.com/tfs/TB1nS7IZNv1gK0jSZFFXXb0sXXa-716-193.png' /img>
<img alt='致远创想' height='40' src='https://img.alicdn.com/tfs/TB13aaKpA9l0K4jSZFKXXXFjpXa-300-300.png' /img>
<img alt='深圳智荟物联技术有限公司' height='40' src='https://img.alicdn.com/tfs/TB1To3amPMZ7e4jSZFOXXX7epXa-1228-500.png' /img>
<img alt='源讯中国' height='40' src='https://img.alicdn.com/tfs/TB1CZuKpA9l0K4jSZFKXXXFjpXa-283-92.png' /img>
<img alt='武汉江寓生活服务有限公司' height='40' src='https://img.alicdn.com/tfs/TB1E4slZFT7gK0jSZFpXXaTkpXa-268-268.png' /img>
<img alt='大账房' height='40' src='https://img.alicdn.com/tfs/TB1.sIyZKL2gK0jSZFmXXc7iXXa-121-121.png' /img>
<img alt='上海阳光喔教育科技有限公司' height='40' src='https://img.alicdn.com/tfs/TB1aUUcZHY1gK0jSZTEXXXDQVXa-246-72.png' /img>
<img alt='北京新学道教育科技有限公司' height='40' src='https://img.alicdn.com/tfs/TB1v3.gZLb2gK0jSZK9XXaEgFXa-240-240.png' /img>
<img alt='北京悦途出行网络科技公司' height='40' src='https://img.alicdn.com/tfs/TB1VHkrZHr1gK0jSZFDXXb9yVXa-248-80.png' /img>
<img alt='上海意贝斯特信息技术有限公司' height='40' src='https://img.alicdn.com/tfs/TB1kGElZUH1gK0jSZSyXXXtlpXa-126-48.png' /img>
<img alt='御家汇' height='40' src='https://img.alicdn.com/tfs/TB1kIIqZUY1gK0jSZFMXXaWcVXa-90-80.png' /img>
<img alt='广州社众软件' height='40' src='https://img.alicdn.com/tfs/TB1CawkZND1gK0jSZFsXXbldVXa-112-112.png' /img>
<img alt='浩鲸科技' height='40' src='https://img.alicdn.com/tfs/TB1fxZqZQL0gK0jSZFAXXcA9pXa-300-300.png' /img>
<img alt='华宇信息' height='40' src='https://img.alicdn.com/tfs/TB1q3UiZKL2gK0jSZPhXXahvXXa-802-271.png' /img>
<img alt='中国云尚科技' height='40' src='https://img.alicdn.com/tfs/TB1uf7bZQL0gK0jSZFtXXXQCXXa-303-65.png' /img>
<img alt='卫宁健康' height='40' src='https://img.alicdn.com/tfs/TB1WMgmZUY1gK0jSZFCXXcwqXXa-189-57.png' /img>
<img alt='聚合联动' height='40' src='https://img.alicdn.com/tfs/TB1gnllpnM11u4jSZPxXXahcXXa-150-60.png' /img>
<img alt='熙菱信息' height='40' src='https://img.alicdn.com/tfs/TB1NJmLpA9l0K4jSZFKXXXFjpXa-195-60.png' /img>
<img alt='鲸算科技' height='40' src='https://img.alicdn.com/tfs/TB1jfCLpA9l0K4jSZFKXXXFjpXa-514-220.png' /img>
<img alt='杭州沃朴物联科技有限公司' height='40' src='https://img.alicdn.com/tfs/TB1vxJ.ZVT7gK0jSZFpXXaTkpXa-309-51.png' /img>
<img alt='深圳市臻络科技有限公司' height='40' src='https://img.alicdn.com/tfs/TB1v5eiZ.T1gK0jSZFrXXcNCXXa-500-41.png' /img>
<img alt='白云电气' height='40' src='https://img.alicdn.com/imgextra/i2/O1CN01QPEPnx1zaOC9n4QXE_!!6000000006730-0-tps-781-100.jpg' /img>
</div>

855
all/pom.xml Normal file
View File

@@ -0,0 +1,855 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 1999-2019 Seata.io Group.
~
~ 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
<version>1.4.2</version>
<name>Seata All-in-one ${project.version}</name>
<url>http://seata.io</url>
<description>Seata is an easy-to-use, high-performance, java based, open source distributed transaction solution.
</description>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<id>Seata</id>
<name>Seata</name>
<url>http://seata.io</url>
</developer>
</developers>
<!-- <organization>-->
<!-- <name>Seata</name>-->
<!-- <url>https://github.com/seata</url>-->
<!-- </organization>-->
<!-- <issueManagement>-->
<!-- <system>github</system>-->
<!-- <url>https://github.com/seata/seata/issues</url>-->
<!-- </issueManagement>-->
<!-- <scm>-->
<!-- <url>git@github.com:seata/seata.git</url>-->
<!-- <connection>scm:git@github.com:seata/seata.git</connection>-->
<!-- <developerConnection>scm:git@github.com:seata/seata.git</developerConnection>-->
<!-- </scm>-->
<properties>
<!-- Compiler settings properties -->
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-bom</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- seata projects -->
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-config-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-config-custom</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-config-apollo</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-config-nacos</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-config-zk</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-config-consul</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-config-etcd3</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-config-spring-cloud</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-discovery-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-discovery-custom</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-discovery-consul</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-discovery-eureka</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-discovery-nacos</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-discovery-redis</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-discovery-sofa</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-discovery-zk</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-discovery-etcd3</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-dubbo</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-http</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-dubbo-alibaba</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-sofa-rpc</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-motan</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-rm</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-rm-datasource</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-sqlparser-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-sqlparser-antlr</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-sqlparser-druid</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-tcc</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-tm</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-serializer-seata</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-serializer-protobuf</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-grpc</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-serializer-kryo</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-serializer-fst</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-serializer-hessian</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-compressor-gzip</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-compressor-7z</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-compressor-bzip2</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-compressor-zip</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-compressor-lz4</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-compressor-deflater</artifactId>
<version>${project.version}</version>
</dependency>
<!-- saga -->
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-saga-processctrl</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-saga-statelang</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-saga-engine</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-saga-rm</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-saga-tm</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-saga-engine-store</artifactId>
<version>${project.version}</version>
</dependency>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<!-- the 3rd part -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>com.typesafe</groupId>
<artifactId>config</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>registry-client-all</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alibaba.spring</groupId>
<artifactId>spring-context-support</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.netflix.eureka</groupId>
<artifactId>eureka-client</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.netflix.archaius</groupId>
<artifactId>archaius-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.ecwid.consul</groupId>
<artifactId>consul-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.etcd</groupId>
<artifactId>jetcd-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>sofa-rpc-all</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.weibo</groupId>
<artifactId>motan-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.weibo</groupId>
<artifactId>motan-transport-netty</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-runtime</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>kryo</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>de.ruedigermoeller</groupId>
<artifactId>fst</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.caucho</groupId>
<artifactId>hessian</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>de.javakaffee</groupId>
<artifactId>kryo-serializers</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.lz4</groupId>
<artifactId>lz4-java</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.5.0.Final</version>
</extension>
</extensions>
<resources>
<resource>
<directory>${user.dir}</directory>
<includes>
<include>LICENSE</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<addMavenDescriptor>true</addMavenDescriptor>
<index>true</index>
<manifest>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Implementation-Build>${maven.build.timestamp}</Implementation-Build>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createSourcesJar>true</createSourcesJar>
<promoteTransitiveDependencies>false</promoteTransitiveDependencies>
<keepDependenciesWithProvidedScope>false</keepDependenciesWithProvidedScope>
<createDependencyReducedPom>true</createDependencyReducedPom>
<artifactSet>
<includes>
<include>io.seata:seata-common</include>
<include>io.seata:seata-core</include>
<include>io.seata:seata-config-core</include>
<include>io.seata:seata-config-custom</include>
<include>io.seata:seata-config-apollo</include>
<include>io.seata:seata-config-nacos</include>
<include>io.seata:seata-config-zk</include>
<include>io.seata:seata-config-consul</include>
<include>io.seata:seata-config-etcd3</include>
<include>io.seata:seata-config-spring-cloud</include>
<include>io.seata:seata-discovery-core</include>
<include>io.seata:seata-discovery-custom</include>
<include>io.seata:seata-discovery-consul</include>
<include>io.seata:seata-discovery-eureka</include>
<include>io.seata:seata-discovery-nacos</include>
<include>io.seata:seata-discovery-redis</include>
<include>io.seata:seata-discovery-sofa</include>
<include>io.seata:seata-discovery-zk</include>
<include>io.seata:seata-discovery-etcd3</include>
<include>io.seata:seata-dubbo</include>
<include>io.seata:seata-dubbo-alibaba</include>
<include>io.seata:seata-motan</include>
<include>io.seata:seata-grpc</include>
<include>io.seata:seata-http</include>
<include>io.seata:seata-rm</include>
<include>io.seata:seata-rm-datasource</include>
<include>io.seata:seata-sqlparser-core</include>
<include>io.seata:seata-sqlparser-antlr</include>
<include>io.seata:seata-sqlparser-druid</include>
<include>io.seata:seata-sofa-rpc</include>
<include>io.seata:seata-spring</include>
<include>io.seata:seata-tcc</include>
<include>io.seata:seata-tm</include>
<include>io.seata:seata-serializer-seata</include>
<include>io.seata:seata-serializer-protobuf</include>
<include>io.seata:seata-serializer-kryo</include>
<include>io.seata:seata-serializer-fst</include>
<include>io.seata:seata-serializer-hessian</include>
<!-- saga -->
<include>io.seata:seata-saga-processctrl</include>
<include>io.seata:seata-saga-statelang</include>
<include>io.seata:seata-saga-engine</include>
<include>io.seata:seata-saga-rm</include>
<include>io.seata:seata-saga-tm</include>
<include>io.seata:seata-saga-engine-store</include>
<!--compressor-->
<include>io.seata:seata-compressor-gzip</include>
<include>io.seata:seata-compressor-7z</include>
<include>io.seata:seata-compressor-bzip2</include>
<include>io.seata:seata-compressor-zip</include>
<include>io.seata:seata-compressor-lz4</include>
<include>io.seata:seata-compressor-deflater</include>
</includes>
</artifactSet>
<transformers>
<!-- META-INF/services -->
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<!-- spring相关 -->
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>file.conf</exclude>
<exclude>registry.conf</exclude>
</excludes>
</filter>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/maven/**</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.0.2</version>
</plugin>
</plugins>
</build>
<!-- <profiles>-->
<!-- <profile>-->
<!-- <id>release</id>-->
<!-- <build>-->
<!-- <plugins>-->
<!-- <plugin>-->
<!-- <groupId>org.apache.maven.plugins</groupId>-->
<!-- <artifactId>maven-javadoc-plugin</artifactId>-->
<!-- <version>2.10.4</version>-->
<!-- <configuration>-->
<!-- <charset>${project.build.sourceEncoding}</charset>-->
<!-- <failOnError>false</failOnError>-->
<!-- <encoding>${project.build.sourceEncoding}</encoding>-->
<!-- <detectOfflineLinks>true</detectOfflineLinks>-->
<!-- <breakiterator>true</breakiterator>-->
<!-- <author>false</author>-->
<!-- <keywords>true</keywords>-->
<!-- <quiet>true</quiet>-->
<!-- <includeDependencySources>true</includeDependencySources>-->
<!-- <dependencySourceIncludes>-->
<!-- <dependencySourceInclude>io.seata:seata-*</dependencySourceInclude>-->
<!-- </dependencySourceIncludes>-->
<!-- </configuration>-->
<!-- <executions>-->
<!-- <execution>-->
<!-- <id>attach-javadocs</id>-->
<!-- <goals>-->
<!-- <goal>jar</goal>-->
<!-- </goals>-->
<!-- </execution>-->
<!-- </executions>-->
<!-- </plugin>-->
<!--&lt;!&ndash; <plugin>&ndash;&gt;-->
<!--&lt;!&ndash; <groupId>org.sonatype.plugins</groupId>&ndash;&gt;-->
<!--&lt;!&ndash; <artifactId>nexus-staging-maven-plugin</artifactId>&ndash;&gt;-->
<!--&lt;!&ndash; <version>1.6.7</version>&ndash;&gt;-->
<!--&lt;!&ndash; <extensions>true</extensions>&ndash;&gt;-->
<!--&lt;!&ndash; <configuration>&ndash;&gt;-->
<!--&lt;!&ndash; <serverId>oss_seata</serverId>&ndash;&gt;-->
<!--&lt;!&ndash; <nexusUrl>https://oss.sonatype.org/</nexusUrl>&ndash;&gt;-->
<!--&lt;!&ndash; <autoReleaseAfterClose>false</autoReleaseAfterClose>&ndash;&gt;-->
<!--&lt;!&ndash; <skipStagingRepositoryClose>true</skipStagingRepositoryClose>&ndash;&gt;-->
<!--&lt;!&ndash; </configuration>&ndash;&gt;-->
<!--&lt;!&ndash; </plugin>&ndash;&gt;-->
<!--&lt;!&ndash; <plugin>&ndash;&gt;-->
<!--&lt;!&ndash; <groupId>org.apache.maven.plugins</groupId>&ndash;&gt;-->
<!--&lt;!&ndash; <artifactId>maven-gpg-plugin</artifactId>&ndash;&gt;-->
<!--&lt;!&ndash; <version>1.6</version>&ndash;&gt;-->
<!--&lt;!&ndash; <executions>&ndash;&gt;-->
<!--&lt;!&ndash; <execution>&ndash;&gt;-->
<!--&lt;!&ndash; <id>sign-artifacts</id>&ndash;&gt;-->
<!--&lt;!&ndash; <phase>verify</phase>&ndash;&gt;-->
<!--&lt;!&ndash; <goals>&ndash;&gt;-->
<!--&lt;!&ndash; <goal>sign</goal>&ndash;&gt;-->
<!--&lt;!&ndash; </goals>&ndash;&gt;-->
<!--&lt;!&ndash; <configuration>&ndash;&gt;-->
<!--&lt;!&ndash; <keyname>A1C4DAB9B220DBA0C277E945D6A1420D747D1EE0</keyname>&ndash;&gt;-->
<!--&lt;!&ndash; </configuration>&ndash;&gt;-->
<!--&lt;!&ndash; </execution>&ndash;&gt;-->
<!--&lt;!&ndash; </executions>&ndash;&gt;-->
<!--&lt;!&ndash; </plugin>&ndash;&gt;-->
<!-- <plugin>-->
<!-- <groupId>org.apache.maven.plugins</groupId>-->
<!-- <artifactId>maven-enforcer-plugin</artifactId>-->
<!-- <version>3.0.0-M3</version>-->
<!-- <executions>-->
<!-- <execution>-->
<!-- <id>enforce-maven</id>-->
<!-- <goals>-->
<!-- <goal>enforce</goal>-->
<!-- </goals>-->
<!-- <configuration>-->
<!-- <rules>-->
<!-- <requireMavenVersion>-->
<!-- <version>[3.6.0,)</version>-->
<!-- </requireMavenVersion>-->
<!-- </rules>-->
<!-- </configuration>-->
<!-- </execution>-->
<!-- </executions>-->
<!-- </plugin>-->
<!-- </plugins>-->
<!-- </build>-->
<!-- -->
<!--&lt;!&ndash; <distributionManagement>&ndash;&gt;-->
<!--&lt;!&ndash; <snapshotRepository>&ndash;&gt;-->
<!--&lt;!&ndash; <id>oss_seata</id>&ndash;&gt;-->
<!--&lt;!&ndash; <url>https://oss.sonatype.org/content/repositories/snapshots</url>&ndash;&gt;-->
<!--&lt;!&ndash; </snapshotRepository>&ndash;&gt;-->
<!--&lt;!&ndash; <repository>&ndash;&gt;-->
<!--&lt;!&ndash; <id>oss_seata</id>&ndash;&gt;-->
<!--&lt;!&ndash; <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>&ndash;&gt;-->
<!--&lt;!&ndash; </repository>&ndash;&gt;-->
<!--&lt;!&ndash; </distributionManagement>&ndash;&gt;-->
<!-- </profile>-->
<!-- </profiles>-->
<!--增加私服仓库配置-->
<distributionManagement>
<repository>
<!--必须与 settings.xml 的 id 一致-->
<id>fantaibao-fantaibao-maven-repository</id>
<name>maven-repository</name>
<url>http://192.168.3.25:18081/nexus/repository/maven-releases/</url>
</repository>
</distributionManagement>
</project>

640
bom/pom.xml Normal file
View File

@@ -0,0 +1,640 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 1999-2019 Seata.io Group.
~
~ 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.
-->
<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">
<groupId>io.seata</groupId>
<artifactId>seata-bom</artifactId>
<version>1.4.2</version>
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<name>Seata bom ${project.version}</name>
<description>Seata bom</description>
<url>http://seata.io</url>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0</url>
<distribution>repo</distribution>
</license>
</licenses>
<!-- <developers>-->
<!-- <developer>-->
<!-- <id>Seata</id>-->
<!-- <name>Seata</name>-->
<!-- <url>http://seata.io</url>-->
<!-- </developer>-->
<!-- </developers>-->
<!-- <organization>-->
<!-- <name>Seata</name>-->
<!-- <url>https://github.com/seata</url>-->
<!-- </organization>-->
<!-- <issueManagement>-->
<!-- <system>github</system>-->
<!-- <url>https://github.com/seata/seata/issues</url>-->
<!-- </issueManagement>-->
<!-- <scm>-->
<!-- <url>git@github.com:seata/seata.git</url>-->
<!-- <connection>scm:git@github.com:seata/seata.git</connection>-->
<!-- <developerConnection>scm:git@github.com:seata/seata.git</developerConnection>-->
<!-- </scm>-->
<properties>
<spring.version>4.3.23.RELEASE</spring.version>
<netty4.version>4.1.30.Final</netty4.version>
<dubbo.version>2.7.0</dubbo.version>
<dubbo.alibaba.version>2.6.5</dubbo.alibaba.version>
<sofa.rpc.version>5.5.3</sofa.rpc.version>
<fastjson.version>1.2.73</fastjson.version>
<protostuff.version>1.5.9</protostuff.version>
<config.version>1.2.1</config.version>
<slf4j-api.version>1.7.22</slf4j-api.version>
<logback-classic.version>1.2.0</logback-classic.version>
<commons-lang.version>2.6</commons-lang.version>
<commons-pool2.version>2.4.2</commons-pool2.version>
<commons-pool.version>1.6</commons-pool.version>
<commons-dbcp2.version>2.7.0</commons-dbcp2.version>
<hikari.version>3.4.3</hikari.version>
<cglib.version>3.1</cglib.version>
<aopalliance.version>1.0</aopalliance.version>
<zkclient.version>0.11</zkclient.version>
<apache-zookeeper.version>3.4.14</apache-zookeeper.version>
<curator-test.version>2.9.1</curator-test.version>
<spring-context-support.version>1.0.2</spring-context-support.version>
<jacoco-maven-plugin.version>0.8.3</jacoco-maven-plugin.version>
<apollo-client.version>1.6.0</apollo-client.version>
<redis-clients.version>3.2.0</redis-clients.version>
<mock-jedis.version>0.1.16</mock-jedis.version>
<eureka-clients.version>1.9.5</eureka-clients.version>
<consul-clients.version>1.4.2</consul-clients.version>
<nacos-client.version>1.3.3</nacos-client.version>
<etcd-client-v3.version>0.3.0</etcd-client-v3.version>
<testcontainers.version>1.11.2</testcontainers.version>
<guava.version>27.0.1-jre</guava.version>
<javax-inject.version>1</javax-inject.version>
<archaius-core.version>0.7.6</archaius-core.version>
<sofa.registry.version>5.2.0</sofa.registry.version>
<httpclient.version>4.5.8</httpclient.version>
<httpcore.version>4.4.11</httpcore.version>
<antlr4.version>4.8</antlr4.version>
<druid.version>1.1.23</druid.version>
<caffeine.version>2.7.0</caffeine.version>
<oracle.client.version>10.2.0.3.0</oracle.client.version>
<mysql.client.version>5.1.35</mysql.client.version>
<postgres.client.version>42.1.4</postgres.client.version>
<h2.version>1.4.181</h2.version>
<motan.version>1.0.0</motan.version>
<jackson.version>2.9.9</jackson.version>
<jcommander.version>1.72</jcommander.version>
<annotation.api.version>1.2</annotation.api.version>
<xz.version>1.8</xz.version>
<commons-compress.version>1.19</commons-compress.version>
<ant.version>1.10.6</ant.version>
<snakeyaml.version>1.26</snakeyaml.version>
<lz4.version>1.7.1</lz4.version>
<!-- Compiler settings properties -->
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<protobuf.version>3.7.1</protobuf.version>
<grpc.version>1.17.1</grpc.version>
<junit.version>4.12</junit.version>
<kryo.version>4.0.2</kryo.version>
<kryo-serializers.version>0.42</kryo-serializers.version>
<hessian.version>4.0.63</hessian.version>
<fst.version>2.57</fst.version>
<groovy.version>2.4.4</groovy.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- the 3rd part -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>${netty4.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4</artifactId>
<version>${antlr4.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>sofa-rpc-all</artifactId>
<version>${sofa.rpc.version}</version>
</dependency>
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-core</artifactId>
<version>${protostuff.version}</version>
</dependency>
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-runtime</artifactId>
<version>${protostuff.version}</version>
</dependency>
<dependency>
<groupId>com.typesafe</groupId>
<artifactId>config</artifactId>
<version>${config.version}</version>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>${snakeyaml.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-api.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback-classic.version}</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>${commons-lang.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>${commons-pool2.version}</version>
</dependency>
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
<version>${commons-pool.version}</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>${protobuf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.alibaba.version}</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>${cglib.version}</version>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>${aopalliance.version}</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>${zkclient.version}</version>
<exclusions>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>io.netty</artifactId>
<groupId>netty</groupId>
</exclusion>
<exclusion>
<artifactId>org.apache.zookeeper</artifactId>
<groupId>zookeeper</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>${apache-zookeeper.version}</version>
<exclusions>
<exclusion>
<artifactId>io.netty</artifactId>
<groupId>netty</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-test</artifactId>
<version>${curator-test.version}</version>
</dependency>
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>registry-client-all</artifactId>
<version>${sofa.registry.version}</version>
</dependency>
<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>registry-test</artifactId>
<version>${sofa.registry.version}</version>
<exclusions>
<exclusion>
<artifactId>log4j-over-slf4j</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>log4j-jcl</artifactId>
<groupId>org.apache.logging.log4j</groupId>
</exclusion>
<exclusion>
<artifactId>log4j-core</artifactId>
<groupId>org.apache.logging.log4j</groupId>
</exclusion>
<exclusion>
<artifactId>log4j-api</artifactId>
<groupId>org.apache.logging.log4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.spring</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring-context-support.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${nacos-client.version}</version>
</dependency>
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>${apollo-client.version}</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>${redis-clients.version}</version>
</dependency>
<dependency>
<groupId>com.github.fppt</groupId>
<artifactId>jedis-mock</artifactId>
<version>${mock-jedis.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.netflix.eureka</groupId>
<artifactId>eureka-client</artifactId>
<version>${eureka-clients.version}</version>
</dependency>
<dependency>
<groupId>com.netflix.archaius</groupId>
<artifactId>archaius-core</artifactId>
<version>${archaius-core.version}</version>
</dependency>
<dependency>
<groupId>com.ecwid.consul</groupId>
<artifactId>consul-api</artifactId>
<version>${consul-clients.version}</version>
</dependency>
<dependency>
<groupId>io.etcd</groupId>
<artifactId>jetcd-core</artifactId>
<version>${etcd-client-v3.version}</version>
<exclusions>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-codec-http</artifactId>
</exclusion>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-codec-http2</artifactId>
</exclusion>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-handler-proxy</artifactId>
</exclusion>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-handler</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>io.etcd</groupId>
<artifactId>jetcd-launcher</artifactId>
<version>${etcd-client-v3.version}</version>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>${testcontainers.version}</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>${javax-inject.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${httpclient.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>${httpcore.version}</version>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>${caffeine.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.client.version}</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgres.client.version}</version>
</dependency>
<dependency>
<groupId>com.weibo</groupId>
<artifactId>motan-core</artifactId>
<version>${motan.version}</version>
<exclusions>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.weibo</groupId>
<artifactId>motan-transport-netty</artifactId>
<version>${motan.version}</version>
<exclusions>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<!--only used for seata-server-->
<dependency>
<groupId>com.beust</groupId>
<artifactId>jcommander</artifactId>
<version>${jcommander.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-testing</artifactId>
<scope>test</scope>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>kryo</artifactId>
<version>${kryo.version}</version>
</dependency>
<dependency>
<groupId>de.javakaffee</groupId>
<artifactId>kryo-serializers</artifactId>
<version>${kryo-serializers.version}</version>
</dependency>
<dependency>
<groupId>com.caucho</groupId>
<artifactId>hessian</artifactId>
<version>${hessian.version}</version>
</dependency>
<dependency>
<groupId>de.ruedigermoeller</groupId>
<artifactId>fst</artifactId>
<version>${fst.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>${commons-dbcp2.version}</version>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>${hikari.version}</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>${annotation.api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.tukaani</groupId>
<artifactId>xz</artifactId>
<version>${xz.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>${commons-compress.version}</version>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>${ant.version}</version>
</dependency>
<dependency>
<groupId>org.lz4</groupId>
<artifactId>lz4-java</artifactId>
<version>${lz4.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>${groovy.version}</version>
<exclusions>
<exclusion>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
</exclusion>
<exclusion>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</dependencyManagement>
<!-- <profiles>-->
<!-- <profile>-->
<!-- <id>release</id>-->
<!-- <build>-->
<!-- <plugins>-->
<!-- <plugin>-->
<!-- <groupId>org.apache.maven.plugins</groupId>-->
<!-- <artifactId>maven-javadoc-plugin</artifactId>-->
<!-- <version>2.10.4</version>-->
<!-- <configuration>-->
<!-- <charset>${project.build.sourceEncoding}</charset>-->
<!-- <failOnError>false</failOnError>-->
<!-- </configuration>-->
<!-- <executions>-->
<!-- <execution>-->
<!-- <phase>package</phase>-->
<!-- <goals>-->
<!-- <goal>jar</goal>-->
<!-- </goals>-->
<!-- </execution>-->
<!-- </executions>-->
<!-- </plugin>-->
<!-- &lt;!&ndash; GPG &ndash;&gt;-->
<!--&lt;!&ndash; <plugin>&ndash;&gt;-->
<!--&lt;!&ndash; <groupId>org.sonatype.plugins</groupId>&ndash;&gt;-->
<!--&lt;!&ndash; <artifactId>nexus-staging-maven-plugin</artifactId>&ndash;&gt;-->
<!--&lt;!&ndash; <version>1.6.7</version>&ndash;&gt;-->
<!--&lt;!&ndash; <extensions>true</extensions>&ndash;&gt;-->
<!--&lt;!&ndash; <configuration>&ndash;&gt;-->
<!--&lt;!&ndash; <serverId>oss_seata</serverId>&ndash;&gt;-->
<!--&lt;!&ndash; <nexusUrl>https://oss.sonatype.org/</nexusUrl>&ndash;&gt;-->
<!--&lt;!&ndash; <autoReleaseAfterClose>false</autoReleaseAfterClose>&ndash;&gt;-->
<!--&lt;!&ndash; <skipStagingRepositoryClose>true</skipStagingRepositoryClose>&ndash;&gt;-->
<!--&lt;!&ndash; </configuration>&ndash;&gt;-->
<!--&lt;!&ndash; </plugin>&ndash;&gt;-->
<!--&lt;!&ndash; <plugin>&ndash;&gt;-->
<!--&lt;!&ndash; <groupId>org.apache.maven.plugins</groupId>&ndash;&gt;-->
<!--&lt;!&ndash; <artifactId>maven-gpg-plugin</artifactId>&ndash;&gt;-->
<!--&lt;!&ndash; <version>1.6</version>&ndash;&gt;-->
<!--&lt;!&ndash; <executions>&ndash;&gt;-->
<!--&lt;!&ndash; <execution>&ndash;&gt;-->
<!--&lt;!&ndash; <id>sign-artifacts</id>&ndash;&gt;-->
<!--&lt;!&ndash; <phase>verify</phase>&ndash;&gt;-->
<!--&lt;!&ndash; <goals>&ndash;&gt;-->
<!--&lt;!&ndash; <goal>sign</goal>&ndash;&gt;-->
<!--&lt;!&ndash; </goals>&ndash;&gt;-->
<!--&lt;!&ndash; <configuration>&ndash;&gt;-->
<!--&lt;!&ndash; <keyname>A1C4DAB9B220DBA0C277E945D6A1420D747D1EE0</keyname>&ndash;&gt;-->
<!--&lt;!&ndash; </configuration>&ndash;&gt;-->
<!--&lt;!&ndash; </execution>&ndash;&gt;-->
<!--&lt;!&ndash; </executions>&ndash;&gt;-->
<!--&lt;!&ndash; </plugin>&ndash;&gt;-->
<!-- <plugin>-->
<!-- <groupId>org.apache.maven.plugins</groupId>-->
<!-- <artifactId>maven-enforcer-plugin</artifactId>-->
<!-- <version>3.0.0-M3</version>-->
<!-- <executions>-->
<!-- <execution>-->
<!-- <id>enforce-maven</id>-->
<!-- <goals>-->
<!-- <goal>enforce</goal>-->
<!-- </goals>-->
<!-- <configuration>-->
<!-- <rules>-->
<!-- <requireMavenVersion>-->
<!-- <version>[3.6.0,)</version>-->
<!-- </requireMavenVersion>-->
<!-- </rules>-->
<!-- </configuration>-->
<!-- </execution>-->
<!-- </executions>-->
<!-- </plugin>-->
<!-- </plugins>-->
<!-- </build>-->
<!--&lt;!&ndash; <distributionManagement>&ndash;&gt;-->
<!--&lt;!&ndash; <snapshotRepository>&ndash;&gt;-->
<!--&lt;!&ndash; <id>oss_seata</id>&ndash;&gt;-->
<!--&lt;!&ndash; <url>https://oss.sonatype.org/content/repositories/snapshots</url>&ndash;&gt;-->
<!--&lt;!&ndash; </snapshotRepository>&ndash;&gt;-->
<!--&lt;!&ndash; <repository>&ndash;&gt;-->
<!--&lt;!&ndash; <id>oss_seata</id>&ndash;&gt;-->
<!--&lt;!&ndash; <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>&ndash;&gt;-->
<!--&lt;!&ndash; </repository>&ndash;&gt;-->
<!--&lt;!&ndash; </distributionManagement>&ndash;&gt;-->
<!-- </profile>-->
<!-- </profiles>-->
<!--增加私服仓库配置-->
<distributionManagement>
<repository>
<!--必须与 settings.xml 的 id 一致-->
<id>fantaibao-fantaibao-maven-repository</id>
<name>maven-repository</name>
<url>http://192.168.3.25:18081/nexus/repository/maven-releases/</url>
</repository>
</distributionManagement>
</project>

5
changeVersion.sh Normal file
View File

@@ -0,0 +1,5 @@
echo "./changeVersion.sh oldVersion newVersion"
echo $1
echo $2
find ./ -name pom.xml | grep -v target | xargs perl -pi -e "s|$1|$2|g"
#find ./ -name Version.java | grep -v target | xargs perl -pi -e "s|$1|$2|g"

176
changes/1.4.2.md Normal file
View File

@@ -0,0 +1,176 @@
### 1.4.2
[source](https://github.com/seata/seata/archive/v1.4.2.zip) |
[binary](https://github.com/seata/seata/releases/download/v1.4.2/seata-server-1.4.2.zip)
<details>
<summary><mark>Release notes</mark></summary>
### Seata 1.4.2
Seata 1.4.2 发布。
Seata 是一款开源的分布式事务解决方案,提供高性能和简单易用的分布式事务服务。
此版本更新如下:
### feature
- [[#3172](https://github.com/seata/seata/pull/3172)] 支持 AT 模式 undo_log 压缩模式
- [[#3372](https://github.com/seata/seata/pull/3372)] 支持saga模式下用户自定义是否更新最后一次重试日志
- [[#3411](https://github.com/seata/seata/pull/3411)] 支持seata-server 线程池参数可配置
- [[#3348](https://github.com/seata/seata/pull/3348)] 支持 TC 存储模式使用 redis-sentinel
- [[#2667](https://github.com/seata/seata/pull/2667)] 支持使用db和redis存储模式时密码的加解密
- [[#3427](https://github.com/seata/seata/pull/3427)] 支持分布式锁接口
- [[#3443](https://github.com/seata/seata/pull/3443)] 支持将seata-server的日志发送到logstash或kafka中
- [[#3486](https://github.com/seata/seata/pull/3486)] 支持Metrics增加事务分组属性
- [[#3317](https://github.com/seata/seata/pull/3317)] 支持当zookeeper作为配置中心时从单node获取全部配置
- [[#2933](https://github.com/seata/seata/pull/2933)] 支持mysql antlr sqlparser
- [[#3228](https://github.com/seata/seata/pull/3228)] 支持自定义序列化插件
- [[#3516](https://github.com/seata/seata/pull/3516)] 支持 consul 作为注册中心和配置中心时的 acl-token
- [[#3116](https://github.com/seata/seata/pull/3116)] 支持配置 apollo 配置中心配置 configService 和 cluster
- [[#3468](https://github.com/seata/seata/pull/3468)] 支持saga模式下任务循环执行
- [[#3447](https://github.com/seata/seata/pull/3447)] 支持日志框架中事务上下文的打印
### bugfix
- [[#3258](https://github.com/seata/seata/pull/3258)] 修复AsyncWorker潜在的OOM问题
- [[#3293](https://github.com/seata/seata/pull/3293)] 修复配置缓存获取值类型不匹配的问题
- [[#3241](https://github.com/seata/seata/pull/3241)] 禁止在多SQL的情况下使用 limit 和 order by 语法
- [[#3406](https://github.com/seata/seata/pull/3406)] 修复当config.txt中包含特殊字符时无法推送至 nacos 的问题
- [[#3367](https://github.com/seata/seata/pull/3367)] 修复最后一个XA分支二阶段时偶发无法回滚的异常
- [[#3418](https://github.com/seata/seata/pull/3418)] 修复 getGeneratedKeys 可能会取到历史的主键的问题
- [[#3448](https://github.com/seata/seata/pull/3448)] 修复多个锁竞争失败时,仅删除单个锁,并优化锁竞争逻辑提升处理性能
- [[#3408](https://github.com/seata/seata/pull/3408)] 修复jar运行模式第三方依赖分离打包时的NPE问题
- [[#3431](https://github.com/seata/seata/pull/3431)] 修复在读取配置时Property Bean可能未初始化的问题
- [[#3413](https://github.com/seata/seata/pull/3413)] 修复回滚到savepoint以及releaseSavepoint的逻辑
- [[#3451](https://github.com/seata/seata/pull/3451)] 修复autoCommit=true全局锁竞争失败时的脏写问题
- [[#3481](https://github.com/seata/seata/pull/3481)] 修复当 consul client 抛出异常时导致刷新任务中断的问题
- [[#3491](https://github.com/seata/seata/pull/3491)] 修复README.md文件中的拼写错误
- [[#3531](https://github.com/seata/seata/pull/3531)] 修复RedisTransactionStoreManager 获取 brachTransaction 可能的 NPE 问题
- [[#3500](https://github.com/seata/seata/pull/3500)] 修复 oracle 和 postgreSql 无法获取 column info 的问题
- [[#3560](https://github.com/seata/seata/pull/3560)] 修复 Committing 状态的事务异步任务没有时间阈值和无法进行事务恢复的问题
- [[#3555](https://github.com/seata/seata/pull/3555)] 通过setBytes代替setBlob避免高版本jdbc驱动工作异常
- [[#3540](https://github.com/seata/seata/pull/3540)] 修复server发布打包时缺失文件的问题
- [[#3597](https://github.com/seata/seata/pull/3597)] 修复可能的 NPE问题
- [[#3568](https://github.com/seata/seata/pull/3568)] 修复自动数据源代理因 ConcurrentHashMap.computeIfAbsent 导致的死锁问题
- [[#3402](https://github.com/seata/seata/pull/3402)] 修复更新SQL中字段名含有库名无法解析更新列的问题
- [[#3464](https://github.com/seata/seata/pull/3464)] 修复测试用例空指针异常和StackTraceLogger中错误的日志格式.
- [[#3522](https://github.com/seata/seata/pull/3522)] 修复当 DML 影响行数为0时注册分支和插入undo_log的问题
- [[#3635](https://github.com/seata/seata/pull/3635)] 修复zookeeper 配置变更无法推送通知的问题
- [[#3133](https://github.com/seata/seata/pull/3133)] 修复某些场景下无法重试全局锁的问题
- [[#3156](https://github.com/seata/seata/pull/3156)] 修复嵌套代理类无法 获取target的问题
### optimize
- [[#3341](https://github.com/seata/seata/pull/3341)] 优化获取指定配置文件的路径格式问题
- [[#3385](https://github.com/seata/seata/pull/3385)] 优化 GitHub Actions 配置,修复单测失败问题
- [[#3175](https://github.com/seata/seata/pull/3175)] 支持雪花算法时钟回拨
- [[#3291](https://github.com/seata/seata/pull/3291)] 优化mysql连接参数
- [[#3336](https://github.com/seata/seata/pull/3336)] 支持使用System.getProperty获取Netty配置参数
- [[#3369](https://github.com/seata/seata/pull/3369)] 添加github action的dockerHub秘钥
- [[#3343](https://github.com/seata/seata/pull/3343)] 将CI程序从Travis CI迁移到Github Actions
- [[#3397](https://github.com/seata/seata/pull/3397)] 增加代码变更记录
- [[#3303](https://github.com/seata/seata/pull/3303)] 支持从nacos单一dataId中读取所有配置
- [[#3380](https://github.com/seata/seata/pull/3380)] 优化 globalTransactionScanner 中的 DISABLE_GLOBAL_TRANSACTION listener
- [[#3123](https://github.com/seata/seata/pull/3123)] 优化 seata-server 打包策略
- [[#3415](https://github.com/seata/seata/pull/3415)] 优化 maven 打包时清除 distribution 目录
- [[#3316](https://github.com/seata/seata/pull/3316)] 优化读取配置值时属性bean未初始化的问题
- [[#3420](https://github.com/seata/seata/pull/3420)] 优化枚举类的使用并添加单元测试
- [[#3533](https://github.com/seata/seata/pull/3533)] 支持获取当前事务角色
- [[#3436](https://github.com/seata/seata/pull/3436)] 优化SQLType类中的错别字
- [[#3439](https://github.com/seata/seata/pull/3439)] 调整springApplicationContextProvider order以使其可以在xml bean之前被调用
- [[#3248](https://github.com/seata/seata/pull/3248)] 优化负载均衡配置迁移到client节点下
- [[#3441](https://github.com/seata/seata/pull/3441)] 优化starter的自动配置处理
- [[#3466](https://github.com/seata/seata/pull/3466)] 优化使用equalsIgnoreCase() 进行字符串比较
- [[#3476](https://github.com/seata/seata/pull/3476)] 支持 server 参数传入hostname时自动将其转换为 ip
- [[#3236](https://github.com/seata/seata/pull/3236)] 优化执行解锁操作的条件,减少不必要的 unlock 操作
- [[#3485](https://github.com/seata/seata/pull/3485)] 删除 ConfigurationFactory 中无用的代码
- [[#3505](https://github.com/seata/seata/pull/3505)] 删除 GlobalTransactionScanner 中无用的 if 判断
- [[#3544](https://github.com/seata/seata/pull/3544)] 优化无法通过Statement#getGeneratedKeys时,只能获取到批量插入的第一个主键的问题
- [[#3549](https://github.com/seata/seata/pull/3549)] 统一DB存储模式下不同表中的xid字段的长度
- [[#3551](https://github.com/seata/seata/pull/3551)] 调大RETRY_DEAD_THRESHOLD的值以及设置成可配置
- [[#3589](https://github.com/seata/seata/pull/3589)] 使用JUnit API做异常检查
- [[#3601](https://github.com/seata/seata/pull/3601)] 使`LoadBalanceProperties``spring-boot:2.x`及以上版本兼容
- [[#3513](https://github.com/seata/seata/pull/3513)] Saga SpringBeanService调用器支持切换 json 解析器
- [[#3318](https://github.com/seata/seata/pull/3318)] 支持 CLIENT_TABLE_META_CHECKER_INTERVAL 可配置化
- [[#3371](https://github.com/seata/seata/pull/3371)] 支持 metric 按 applicationId 分组
- [[#3459](https://github.com/seata/seata/pull/3459)] 删除重复的ValidadAddress代码
- [[#3215](https://github.com/seata/seata/pull/3215)] 优化seata-server 在file模式下启动时的reload逻辑
- [[#3631](https://github.com/seata/seata/pull/3631)] 优化 nacos-config.py 脚本的入参问题
- [[#3638](https://github.com/seata/seata/pull/3638)] 优化 update 和 delete 的 SQL 不支持 join 的错误提示
- [[#3523](https://github.com/seata/seata/pull/3523)] 优化当使用oracle时调用releaseSavepoint()方法报异常的问题
- [[#3458](https://github.com/seata/seata/pull/3458)] 还原已删除的md
- [[#3574](https://github.com/seata/seata/pull/3574)] 修复EventBus.java文件中注释拼写错误
- [[#3573](https://github.com/seata/seata/pull/3573)] 修复 README.md 文件中设计器路径错误
- [[#3662](https://github.com/seata/seata/pull/3662)] 更新gpg密钥对
- [[#3664](https://github.com/seata/seata/pull/3664)] 优化 javadoc
- [[#3637](https://github.com/seata/seata/pull/3637)] 登记使用seata的公司和1.4.2版本包含的新增pr信息
### test
- [[#3381](https://github.com/seata/seata/pull/3381)] 添加 TmClient 的测试用例
- [[#3607](https://github.com/seata/seata/pull/3607)] 修复 EventBus 的单元测试问题
- [[#3579](https://github.com/seata/seata/pull/3579)] 添加 StringFormatUtils 测试用例
- [[#3365](https://github.com/seata/seata/pull/3365)] 修复ParameterParserTest测试用例
- [[#3359](https://github.com/seata/seata/pull/3359)] 删除未使用的测试用例
- [[#3383](https://github.com/seata/seata/pull/3383)] 优化StatementProxyTest单元测试
- [[#3578](https://github.com/seata/seata/pull/3578)] 修复单元测试case里的UnfinishedStubbing异常
非常感谢以下 contributors 的代码贡献。若有无意遗漏,请报告。
- [slievrly](https://github.com/slievrly)
- [caohdgege](https://github.com/caohdgege)
- [a364176773](https://github.com/a364176773)
- [wangliang181230](https://github.com/wangliang181230)
- [xingfudeshi](https://github.com/xingfudeshi)
- [jsbxyyx](https://github.com/jsbxyyx)
- [selfishlover](https://github.com/selfishlover)
- [l8189352](https://github.com/l81893521)
- [Rubbernecker](https://github.com/Rubbernecker)
- [lj2018110133](https://github.com/lj2018110133)
- [github-ganyu](https://github.com/github-ganyu)
- [dmego](https://github.com/dmego)
- [spilledyear](https://github.com/spilledyear)
- [hoverruan](https://github.com/hoverruan )
- [anselleeyy](https://github.com/anselleeyy)
- [Ifdevil](https://github.com/Ifdevil)
- [lvxianzheng](https://github.com/lvxianzheng)
- [MentosL](https://github.com/MentosL)
- [lian88jian](https://github.com/lian88jian)
- [litianyu1992](https://github.com/litianyu1992)
- [xyz327](https://github.com/xyz327)
- [13414850431](https://github.com/13414850431)
- [xuande](https://github.com/xuande)
- [tanggen](https://github.com/tanggen)
- [eas5](https://github.com/eas5)
- [nature80](https://github.com/nature80)
- [ls9527](https://github.com/ls9527)
- [drgnchan](https://github.com/drgnchan)
- [imyangyong](https://github.com/imyangyong)
- [sunlggggg](https://github.com/sunlggggg)
- [long187](https://github.com/long187)
- [h-zhi](https://github.com/h-zhi)
- [StellaiYang](https://github.com/StellaiYang)
- [slinpq](https://github.com/slinpq)
- [sustly](https://github.com/sustly)
- [cznc](https://github.com/cznc)
- [squallliu](https://github.com/squallliu)
- [81519434](https://github.com/81519434)
- [luoxn28](https://github.com/luoxn28)
同时我们收到了社区反馈的很多有价值的issue和建议非常感谢大家。
#### Link
- **Seata:** https://github.com/seata/seata
- **Seata-Samples:** https://github.com/seata/seata-samples
- **Release:** https://github.com/seata/seata/releases
- **WebSite:** https://seata.io
</details>

177
changes/en-us/1.4.2.md Normal file
View File

@@ -0,0 +1,177 @@
### 1.4.2
[source](https://github.com/seata/seata/archive/v1.4.2.zip) |
[binary](https://github.com/seata/seata/releases/download/v1.4.2/seata-server-1.4.2.zip)
<details>
<summary><mark>Release notes</mark></summary>
### Seata 1.4.2
Seata 1.4.2 Released.
Seata is an easy-to-use, high-performance, open source distributed transaction solution.
The version is updated as follows:
### feature
- [[#3172](https://github.com/seata/seata/pull/3172)] support undo_loge compression mode in AT
- [[#3372](https://github.com/seata/seata/pull/3372)] Saga support customize whether update last retry log
- [[#3411](https://github.com/seata/seata/pull/3411)] support seata server thread pool parameters configuration
- [[#3348](https://github.com/seata/seata/pull/3348)] support redis sentinel storage mode in TC
- [[#2667](https://github.com/seata/seata/pull/2667)] support password decryption when using db and redis storage mode
- [[#3427](https://github.com/seata/seata/pull/3427)] add distributed lock interface
- [[#3443](https://github.com/seata/seata/pull/3443)] send the `seata-server` log to `logstash` or `kafka`
- [[#3486](https://github.com/seata/seata/pull/3486)] add transaction service group for metric
- [[#3317](https://github.com/seata/seata/pull/3317)] support to obtain multiple configurations through a single node when using zookeeper as configuration center
- [[#2933](https://github.com/seata/seata/pull/2933)] add antlr for mysql sqlparser
- [[#3228](https://github.com/seata/seata/pull/3228)] support custom serialization plugin
- [[#3516](https://github.com/seata/seata/pull/3516)] support acl-token when consul is used registry and configuration center
- [[#3116](https://github.com/seata/seata/pull/3116)] support configuring apolloService and apolloCluster
- [[#3468](https://github.com/seata/seata/pull/3468)] saga support loop execution on state
- [[#3447](https://github.com/seata/seata/pull/3447)] support Transaction context printing in logging framework
### bugfix
- [[#3258](https://github.com/seata/seata/pull/3258)] fix AsyncWorker potential OOM problem
- [[#3293](https://github.com/seata/seata/pull/3293)] fix configuration cache get value type mismatch exception
- [[#3241](https://github.com/seata/seata/pull/3241)] forbidden use order by or limit in multi sql
- [[#3406](https://github.com/seata/seata/pull/3406)] fix the value can not be push to nacos when special charset in config.txt
- [[#3418](https://github.com/seata/seata/pull/3418)] fix getGeneratedKeys may get history pk
- [[#3408](https://github.com/seata/seata/pull/3408)] fix the NPE problem of jar running mode when the third-dependency on separate packaging
- [[#3431](https://github.com/seata/seata/pull/3431)] fix property bean may not be initialized when reading configuration
- [[#3413](https://github.com/seata/seata/pull/3413)] fix the logic of rollback to savepoint and release to savepoint
- [[#3367](https://github.com/seata/seata/pull/3367)] when the xa branch is rollback, it cannot be executed due to idle state
- [[#3448](https://github.com/seata/seata/pull/3448)] reduce unnecessary competition and remove missing locks
- [[#3451](https://github.com/seata/seata/pull/3451)] fix set auto-commit to true when local transactions are not being used. Failure to compete for a lock causes the global transaction to exit, invaliding the global row lock and dirty writing of the data.
- [[#3481](https://github.com/seata/seata/pull/3481)] fix seata node refresh failure because of consul client throws exceptions
- [[#3491](https://github.com/seata/seata/pull/3491)] fix typo in README.md
- [[#3531](https://github.com/seata/seata/pull/3531)] fix the NPE of RedisTransactionStoreManager when get branch transactions
- [[#3500](https://github.com/seata/seata/pull/3500)] fix oracle and postgreSQL can't query column info
- [[#3560](https://github.com/seata/seata/pull/3560)] fix the problem that the asynchronous task of the transactions in the committing state has no time threshold and cannot recover the transaction
- [[#3555](https://github.com/seata/seata/pull/3555)] do not call setBlob to invalid the jdbc exception
- [[#3540](https://github.com/seata/seata/pull/3540)] fix server distribution missing files
- [[#3597](https://github.com/seata/seata/pull/3597)] fix the possible NPE
- [[#3568](https://github.com/seata/seata/pull/3568)] fix automatic datasource agent caused by ConcurrentHashMap.computeIfAbsent Deadlock problem
- [[#3402](https://github.com/seata/seata/pull/3402)] fix the problem that the updated column cannot be resolved because the field name in the updated SQL contains the database name
- [[#3464](https://github.com/seata/seata/pull/3464)] fix test case NPE and StackTraceLogger's log.
- [[#3522](https://github.com/seata/seata/pull/3522)] fix register branch and store undolog when AT branch does not need compete lock
- [[#3635](https://github.com/seata/seata/pull/3635)] fix pushing notification failed when the configuration changed in zookeeper
- [[#3133](https://github.com/seata/seata/pull/3133)] fix the case that could not retry acquire global lock
- [[#3156](https://github.com/seata/seata/pull/3156)] optimize the logic of SpringProxyUtils.findTargetClass
### optimize
- [[#3341](https://github.com/seata/seata/pull/3341)] optimize the format of the path to the specified configuration file
- [[#3385](https://github.com/seata/seata/pull/3385)] optimize github action and fix unit test failure
- [[#3175](https://github.com/seata/seata/pull/3175)] improve UUIDGenerator using "history time" version of snowflake algorithm
- [[#3291](https://github.com/seata/seata/pull/3291)] mysql jdbc connect param
- [[#3336](https://github.com/seata/seata/pull/3336)] support using System.getProperty to get netty config property
- [[#3369](https://github.com/seata/seata/pull/3369)] add github action secrets env for dockerHub
- [[#3343](https://github.com/seata/seata/pull/3343)] Migrate CI provider from Travis CI to Github Actions
- [[#3397](https://github.com/seata/seata/pull/3397)] add the change records folder
- [[#3303](https://github.com/seata/seata/pull/3303)] supports reading all configurations from a single Nacos dataId
- [[#3380](https://github.com/seata/seata/pull/3380)] globalTransactionScanner listener optimize
- [[#3123](https://github.com/seata/seata/pull/3123)] optimize the packing strategy of seata-server
- [[#3415](https://github.com/seata/seata/pull/3415)] optimize maven clean plugin to clear the distribution directory
- [[#3316](https://github.com/seata/seata/pull/3316)] optimize the property bean may not be initialized while reading config value
- [[#3420](https://github.com/seata/seata/pull/3420)] optimize enumerated classes and add unit tests
- [[#3533](https://github.com/seata/seata/pull/3533)] added interface to get current transaction role
- [[#3436](https://github.com/seata/seata/pull/3436)] optimize typo in SQLType class
- [[#3439](https://github.com/seata/seata/pull/3439)] adjust the order of springApplicationContextProvider so that it can be called before the XML bean
- [[#3248](https://github.com/seata/seata/pull/3248)] optimize the config of load-balance migration to belong the client node
- [[#3441](https://github.com/seata/seata/pull/3441)] optimize the auto-configuration processing of starter
- [[#3466](https://github.com/seata/seata/pull/3466)] String comparison uses equalsIgnoreCase()
- [[#3476](https://github.com/seata/seata/pull/3476)] support when the server parameter passed is hostname, it will be automatically converted to IP
- [[#3236](https://github.com/seata/seata/pull/3236)] optimize the conditions for executing unlocking
- [[#3485](https://github.com/seata/seata/pull/3485)] optimize useless codes in ConfigurationFactory
- [[#3505](https://github.com/seata/seata/pull/3505)] optimize useless if judgments in the GlobalTransactionScanner class
- [[#3544](https://github.com/seata/seata/pull/3544)] optimize the get pks by auto when auto generated keys is false
- [[#3549](https://github.com/seata/seata/pull/3549)] unified the length of xid in different tables when using DB storage mode
- [[#3551](https://github.com/seata/seata/pull/3551)] make RETRY_DEAD_THRESHOLD bigger and configurable
- [[#3589](https://github.com/seata/seata/pull/3589)] Changed exception check by JUnit API usage
- [[#3601](https://github.com/seata/seata/pull/3601)] make `LoadBalanceProperties` compatible with `spring-boot:2.x` and above
- [[#3513](https://github.com/seata/seata/pull/3513)] Saga SpringBeanService invoker support switch json parser
- [[#3318](https://github.com/seata/seata/pull/3318)] make CLIENT_TABLE_META_CHECKER_INTERVAL configurable
- [[#3371](https://github.com/seata/seata/pull/3371)] add applicationId for metric
- [[#3459](https://github.com/seata/seata/pull/3459)] remove duplicate validAddress code
- [[#3215](https://github.com/seata/seata/pull/3215)] opt the reload during startup in file mode
- [[#3631](https://github.com/seata/seata/pull/3631)] optimize nacos-config.py parameter
- [[#3638](https://github.com/seata/seata/pull/3638)] optimize the error when use update or delete with join in sql
- [[#3523](https://github.com/seata/seata/pull/3523)] optimize release savepoint when use oracle
- [[#3458](https://github.com/seata/seata/pull/3458)] reversion the deleted md
- [[#3574](https://github.com/seata/seata/pull/3574)] repair Spelling errors in comments in EventBus.java files
- [[#3573](https://github.com/seata/seata/pull/3573)] fix designer directory path in README.md
- [[#3662](https://github.com/seata/seata/pull/3662)] update gpg key
- [[#3664](https://github.com/seata/seata/pull/3664)] optimize some javadocs
- [[#3637](https://github.com/seata/seata/pull/3637)] register the participating companies and pull request information
### test
- [[#3381](https://github.com/seata/seata/pull/3381)] test case for tmClient
- [[#3607](https://github.com/seata/seata/pull/3607)] fixed bugs in EventBus unit tests
- [[#3579](https://github.com/seata/seata/pull/3579)] add test case for StringFormatUtils
- [[#3365](https://github.com/seata/seata/pull/3365)] optimize ParameterParserTest test case failed
- [[#3359](https://github.com/seata/seata/pull/3359)] remove unused test case
- [[#3578](https://github.com/seata/seata/pull/3578)] fix UnfinishedStubbing Exception in unit test case
- [[#3383](https://github.com/seata/seata/pull/3383)] optimize StatementProxyTest unit test
Thanks to these contributors for their code commits. Please report an unintended omission.
- [slievrly](https://github.com/slievrly)
- [caohdgege](https://github.com/caohdgege)
- [a364176773](https://github.com/a364176773)
- [wangliang181230](https://github.com/wangliang181230)
- [xingfudeshi](https://github.com/xingfudeshi)
- [jsbxyyx](https://github.com/jsbxyyx)
- [selfishlover](https://github.com/selfishlover)
- [l8189352](https://github.com/l81893521)
- [Rubbernecker](https://github.com/Rubbernecker)
- [lj2018110133](https://github.com/lj2018110133)
- [github-ganyu](https://github.com/github-ganyu)
- [dmego](https://github.com/dmego)
- [spilledyear](https://github.com/spilledyear)
- [hoverruan](https://github.com/hoverruan )
- [anselleeyy](https://github.com/anselleeyy)
- [Ifdevil](https://github.com/Ifdevil)
- [lvxianzheng](https://github.com/lvxianzheng)
- [MentosL](https://github.com/MentosL)
- [lian88jian](https://github.com/lian88jian)
- [litianyu1992](https://github.com/litianyu1992)
- [xyz327](https://github.com/xyz327)
- [13414850431](https://github.com/13414850431)
- [xuande](https://github.com/xuande)
- [tanggen](https://github.com/tanggen)
- [eas5](https://github.com/eas5)
- [nature80](https://github.com/nature80)
- [ls9527](https://github.com/ls9527)
- [drgnchan](https://github.com/drgnchan)
- [imyangyong](https://github.com/imyangyong)
- [sunlggggg](https://github.com/sunlggggg)
- [long187](https://github.com/long187)
- [h-zhi](https://github.com/h-zhi)
- [StellaiYang](https://github.com/StellaiYang)
- [slinpq](https://github.com/slinpq)
- [sustly](https://github.com/sustly)
- [cznc](https://github.com/cznc)
- [squallliu](https://github.com/squallliu)
- [81519434](https://github.com/81519434)
- [luoxn28](https://github.com/luoxn28)
Also, we receive many valuable issues, questions and advices from our community. Thanks for you all.
#### Link
- **Seata:** https://github.com/seata/seata
- **Seata-Samples:** https://github.com/seata/seata-samples
- **Release:** https://github.com/seata/seata/releases
- **WebSite:** https://seata.io
</details>

25
codecov.yml Normal file
View File

@@ -0,0 +1,25 @@
codecov:
require_ci_to_pass: yes
coverage:
status:
patch: no
project:
default:
threshold: 1%
if_not_found: success
changes: no
precision: 2
range: "50...100"
ignore:
- "test/.*"
- ".github/.*"
- ".mvn/.*"
- ".style/.*"
- "*.md"
- "rm-datasource/src/test/java/io/seata/rm/datasource/mock"
- "sqlparser/seata-sqlparser-antlr/src/main/java/io/seata/sqlparser/antlr/mysql/antlr/.*"
- "sqlparser/seata-sqlparser-antlr/src/main/java/io/seata/sqlparser/antlr/mysql/parser/.*"
comment:
layout: "reach,diff,flags,tree"
behavior: default
require_changes: no

43
common/pom.xml Normal file
View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 1999-2019 Seata.io Group.
~
~ 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.
-->
<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>io.seata</groupId>
<artifactId>seata-parent</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>seata-common</artifactId>
<packaging>jar</packaging>
<name>seata-common ${project.version}</name>
<dependencies>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,160 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common;
import java.nio.charset.Charset;
/**
* The type Constants.
*
* @author slievrly
*/
public interface Constants {
/**
* The constant IP_PORT_SPLIT_CHAR.
*/
String IP_PORT_SPLIT_CHAR = ":";
/**
* The constant CLIENT_ID_SPLIT_CHAR.
*/
String CLIENT_ID_SPLIT_CHAR = ":";
/**
* The constant ENDPOINT_BEGIN_CHAR.
*/
String ENDPOINT_BEGIN_CHAR = "/";
/**
* The constant DBKEYS_SPLIT_CHAR.
*/
String DBKEYS_SPLIT_CHAR = ",";
/**
* The constant ROW_LOCK_KEY_SPLIT_CHAR.
*/
String ROW_LOCK_KEY_SPLIT_CHAR = ";";
/**
* the start time of transaction
*/
String START_TIME = "start-time";
/**
* app name
*/
String APP_NAME = "appName";
/**
* TCC start time
*/
String ACTION_START_TIME = "action-start-time";
/**
* TCC name
*/
String ACTION_NAME = "actionName";
/**
* phase one method name
*/
String PREPARE_METHOD = "sys::prepare";
/**
* phase two commit method name
*/
String COMMIT_METHOD = "sys::commit";
/**
* phase two rollback method name
*/
String ROLLBACK_METHOD = "sys::rollback";
/**
* host ip
*/
String HOST_NAME = "host-name";
/**
* The constant TCC_METHOD_RESULT.
*/
String TCC_METHOD_RESULT = "result";
/**
* The constant TCC_METHOD_ARGUMENTS.
*/
String TCC_METHOD_ARGUMENTS = "arguments";
/**
* transaction context
*/
String TCC_ACTIVITY_CONTEXT = "activityContext";
/**
* branch context
*/
String TCC_ACTION_CONTEXT = "actionContext";
/**
* default charset name
*/
String DEFAULT_CHARSET_NAME = "UTF-8";
/**
* default charset is utf-8
*/
Charset DEFAULT_CHARSET = Charset.forName(DEFAULT_CHARSET_NAME);
/**
* The constant OBJECT_KEY_SPRING_APPLICATION_CONTEXT
*/
String OBJECT_KEY_SPRING_APPLICATION_CONTEXT = "springApplicationContext";
/**
* The constant BEAN_NAME_SPRING_APPLICATION_CONTEXT_PROVIDER
*/
String BEAN_NAME_SPRING_APPLICATION_CONTEXT_PROVIDER = "springApplicationContextProvider";
/**
* The constant BEAN_NAME_FAILURE_HANDLER
*/
String BEAN_NAME_FAILURE_HANDLER = "failureHandler";
/**
* The constant SAGA_TRANS_NAME_PREFIX
*/
String SAGA_TRANS_NAME_PREFIX = "$Saga_";
/**
* The constant RETRY_ROLLBACKING
*/
String RETRY_ROLLBACKING = "RetryRollbacking";
/**
* The constant RETRY_COMMITTING
*/
String RETRY_COMMITTING = "RetryCommitting";
/**
* The constant ASYNC_COMMITTING
*/
String ASYNC_COMMITTING = "AsyncCommitting";
/**
* The constant TX_TIMEOUT_CHECK
*/
String TX_TIMEOUT_CHECK = "TxTimeoutCheck";
/**
* The constant UNDOLOG_DELETE
*/
String UNDOLOG_DELETE = "UndologDelete";
}

View File

@@ -0,0 +1,122 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common;
import java.util.concurrent.ThreadLocalRandom;
/**
* @author xingfudeshi@gmail.com
*/
public interface DefaultValues {
int DEFAULT_CLIENT_LOCK_RETRY_INTERVAL = 10;
int DEFAULT_TM_DEGRADE_CHECK_ALLOW_TIMES = 10;
int DEFAULT_CLIENT_LOCK_RETRY_TIMES = 30;
boolean DEFAULT_CLIENT_LOCK_RETRY_POLICY_BRANCH_ROLLBACK_ON_CONFLICT = true;
int DEFAULT_LOG_EXCEPTION_RATE = 100;
int DEFAULT_CLIENT_ASYNC_COMMIT_BUFFER_LIMIT = 10000;
int DEFAULT_TM_DEGRADE_CHECK_PERIOD = 2000;
int DEFAULT_CLIENT_REPORT_RETRY_COUNT = 5;
boolean DEFAULT_CLIENT_REPORT_SUCCESS_ENABLE = false;
boolean DEFAULT_CLIENT_TABLE_META_CHECK_ENABLE = false;
long DEFAULT_TABLE_META_CHECKER_INTERVAL = 60000L;
boolean DEFAULT_TM_DEGRADE_CHECK = false;
boolean DEFAULT_CLIENT_SAGA_BRANCH_REGISTER_ENABLE = false;
boolean DEFAULT_CLIENT_SAGA_RETRY_PERSIST_MODE_UPDATE = false;
boolean DEFAULT_CLIENT_SAGA_COMPENSATE_PERSIST_MODE_UPDATE = false;
/**
* Shutdown timeout default 3s
*/
int DEFAULT_SHUTDOWN_TIMEOUT_SEC = 3;
int DEFAULT_SELECTOR_THREAD_SIZE = 1;
int DEFAULT_BOSS_THREAD_SIZE = 1;
String DEFAULT_SELECTOR_THREAD_PREFIX = "NettyClientSelector";
String DEFAULT_WORKER_THREAD_PREFIX = "NettyClientWorkerThread";
boolean DEFAULT_ENABLE_CLIENT_BATCH_SEND_REQUEST = true;
String DEFAULT_BOSS_THREAD_PREFIX = "NettyBoss";
String DEFAULT_NIO_WORKER_THREAD_PREFIX = "NettyServerNIOWorker";
String DEFAULT_EXECUTOR_THREAD_PREFIX = "NettyServerBizHandler";
boolean DEFAULT_TRANSPORT_HEARTBEAT = true;
boolean DEFAULT_TRANSACTION_UNDO_DATA_VALIDATION = true;
String DEFAULT_TRANSACTION_UNDO_LOG_SERIALIZATION = "jackson";
boolean DEFAULT_ONLY_CARE_UPDATE_COLUMNS = true;
/**
* The constant DEFAULT_TRANSACTION_UNDO_LOG_TABLE.
*/
String DEFAULT_TRANSACTION_UNDO_LOG_TABLE = "undo_log";
/**
* The constant DEFAULT_STORE_DB_GLOBAL_TABLE.
*/
String DEFAULT_STORE_DB_GLOBAL_TABLE = "global_table";
/**
* The constant DEFAULT_STORE_DB_BRANCH_TABLE.
*/
String DEFAULT_STORE_DB_BRANCH_TABLE = "branch_table";
/**
* The constant DEFAULT_LOCK_DB_TABLE.
*/
String DEFAULT_LOCK_DB_TABLE = "lock_table";
int DEFAULT_TM_COMMIT_RETRY_COUNT = 5;
int DEFAULT_TM_ROLLBACK_RETRY_COUNT = 5;
int DEFAULT_GLOBAL_TRANSACTION_TIMEOUT = 60000;
String DEFAULT_TX_GROUP = "my_test_tx_group";
String DEFAULT_TC_CLUSTER = "default";
String DEFAULT_GROUPLIST = "127.0.0.1:8091";
String DEFAULT_DATA_SOURCE_PROXY_MODE = "AT";
boolean DEFAULT_DISABLE_GLOBAL_TRANSACTION = false;
int SERVER_DEFAULT_PORT = 8091;
String SERVER_DEFAULT_STORE_MODE = "file";
long SERVER_DEFAULT_NODE = ThreadLocalRandom.current().nextLong(1024);
String DEFAULT_SAGA_JSON_PARSER = "fastjson";
boolean DEFAULT_SERVER_ENABLE_CHECK_AUTH = true;
String DEFAULT_LOAD_BALANCE = "RandomLoadBalance";
int VIRTUAL_NODES_DEFAULT = 10;
/**
* the constant DEFAULT_CLIENT_UNDO_COMPRESS_ENABLE
*/
boolean DEFAULT_CLIENT_UNDO_COMPRESS_ENABLE = true;
/**
* the constant DEFAULT_CLIENT_UNDO_COMPRESS_TYPE
*/
String DEFAULT_CLIENT_UNDO_COMPRESS_TYPE = "zip";
/**
* the constant DEFAULT_CLIENT_UNDO_COMPRESS_THRESHOLD
*/
String DEFAULT_CLIENT_UNDO_COMPRESS_THRESHOLD = "64k";
/**
* the constant DEFAULT_RETRY_DEAD_THRESHOLD
*/
int DEFAULT_RETRY_DEAD_THRESHOLD = 2 * 60 * 1000 + 10 * 1000;
}

View File

@@ -0,0 +1,89 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common;
/**
* The type Xid.
*
* @author slievrly
*/
public class XID {
private static int port;
private static String ipAddress;
/**
* Sets port.
*
* @param port the port
*/
public static void setPort(int port) {
XID.port = port;
}
/**
* Sets ip address.
*
* @param ipAddress the ip address
*/
public static void setIpAddress(String ipAddress) {
XID.ipAddress = ipAddress;
}
/**
* Generate xid string.
*
* @param tranId the tran id
* @return the string
*/
public static String generateXID(long tranId) {
return ipAddress + ":" + port + ":" + tranId;
}
/**
* Gets transaction id.
*
* @param xid the xid
* @return the transaction id
*/
public static long getTransactionId(String xid) {
if (xid == null) {
return -1;
}
int idx = xid.lastIndexOf(":");
return Long.parseLong(xid.substring(idx + 1));
}
/**
* Gets port.
*
* @return the port
*/
public static int getPort() {
return port;
}
/**
* Gets ip address.
*
* @return the ip address
*/
public static String getIpAddress() {
return ipAddress;
}
}

View File

@@ -0,0 +1,75 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.exception;
/**
* the data access exception
* @author jsbxyyx
*/
public class DataAccessException extends StoreException {
/**
* default constructor
*/
public DataAccessException() {
}
/**
* constructor with framework error code
* @param err the framework error code
*/
public DataAccessException(FrameworkErrorCode err) {
super(err);
}
/**
* constructor with msg
* @param msg the msg
*/
public DataAccessException(String msg) {
super(msg);
}
/**
* constructor with cause
* @param cause the cause
*/
public DataAccessException(Throwable cause) {
super(cause);
}
/**
* constructor with msg and framework error code
* @param msg the msg
* @param errCode the framework error code
*/
public DataAccessException(String msg, FrameworkErrorCode errCode) {
super(msg, errCode);
}
/**
* constructor with cause and msg and framework error code
* @param cause the throwable
* @param msg the msg
* @param errCode the framework error code
*/
public DataAccessException(Throwable cause, String msg, FrameworkErrorCode errCode) {
super(cause, msg, errCode);
}
}

View File

@@ -0,0 +1,58 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.exception;
/**
* eureka registry exception
*
* @author: rui_849217@163.com
*/
public class EurekaRegistryException extends RuntimeException {
/**
* eureka registry exception.
*/
public EurekaRegistryException() {
super();
}
/**
* eureka registry exception.
*
* @param message the message
*/
public EurekaRegistryException(String message) {
super(message);
}
/**
* eureka registry exception.
*
* @param message the message
* @param cause the cause
*/
public EurekaRegistryException(String message, Throwable cause) {
super(message, cause);
}
/**
* eureka registry exception.
*
* @param cause the cause
*/
public EurekaRegistryException(Throwable cause) {
super(cause);
}
}

View File

@@ -0,0 +1,257 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.exception;
/**
* The enum Framework error code.
*
* @author slievrly
*/
public enum FrameworkErrorCode {
/**
* 0001 ~ 0099 Configuration related errors
*/
ThreadPoolFull("0004", "Thread pool is full", "Please check the thread pool configuration"),
/**
* The Init services client error.
*/
InitSeataClientError("0008", "Seata app name or seata server group is null", "Please check your configuration"),
/**
* The Null rule error.
*/
NullRuleError("0010", "Services rules is null", "Please check your configuration"),
/**
* 0101 ~ 0199 Network related error. (Not connected, disconnected, dispatched, etc.)
*/
NetConnect("0101", "Can not connect to the server", "Please check if the seata service is started. Is the network connection to the seata server normal?"),
/**
* The Net reg appname.
*/
NetRegAppname("0102", "Register client app name failed", "Please check if the seata service is started. Is the network connection to the seata server normal?"),
/**
* The Net disconnect.
*/
NetDisconnect("0103", "Seata connection closed", "The network is disconnected. Please check the network connection to the client or seata server."),
/**
* The Net dispatch.
*/
NetDispatch("0104", "Dispatch error", "Network processing error. Please check the network connection to the client or seata server."),
/**
* The Net on message.
*/
NetOnMessage("0105", "On message error", "Network processing error. Please check the network connection to the client or seata server."),
/**
* Get channel error framework error code.
*/
getChannelError("0106", "Get channel error", "Get channel error"),
/**
* Channel not writable framework error code.
*/
ChannelNotWritable("0107", "Channel not writable", "Channel not writable"),
/**
* Send half message failed framework error code.
*/
SendHalfMessageFailed("0108", "Send half message failed", "Send half message failed"),
/**
* Channel is not writable framework error code.
*/
ChannelIsNotWritable("0109", "Channel is not writable", "Channel is not writable"),
/**
* No available service framework error code.
*/
NoAvailableService("0110", "No available service", "No available service"),
/**
* Invalid configuration framework error code.
*/
InvalidConfiguration("0201", "Invalid configuration", "Invalid configuration"),
/**
* Exception caught framework error code.
*/
ExceptionCaught("0318", "Exception caught", "Exception caught"),
/**
* Register rm framework error code.
*/
RegisterRM("0304", "Register RM failed", "Register RM failed"),
/** 0400~0499 Saga related error **/
/**
* Process type not found
*/
ProcessTypeNotFound("0401", "Process type not found", "Process type not found"),
/**
* Process handler not found
*/
ProcessHandlerNotFound("0402", "Process handler not found", "Process handler not found"),
/**
* Process router not found
*/
ProcessRouterNotFound("0403", "Process router not found", "Process router not found"),
/**
* method not public
*/
MethodNotPublic("0404", "method not public", "method not public"),
/**
* method invoke error
*/
MethodInvokeError("0405", "method invoke error", "method invoke error"),
/**
* CompensationState not found
*/
CompensationStateNotFound("0406", "CompensationState not found", "CompensationState not found"),
/**
* Evaluation returns null
*/
EvaluationReturnsNull("0407", "Evaluation returns null", "Evaluation returns null"),
/**
* Evaluation returns non-Boolean
*/
EvaluationReturnsNonBoolean("0408", "Evaluation returns non-Boolean", "Evaluation returns non-Boolean"),
/**
* Not a exception class
*/
NotExceptionClass("0409", "Not a exception class", "Not a exception class"),
/**
* No such method
*/
NoSuchMethod("0410", "No such method", "No such method"),
/**
* Object not exists
*/
ObjectNotExists("0411", "Object not exists", "Object not exists"),
/**
* Parameter required
*/
ParameterRequired("0412", "Parameter required", "Parameter required"),
/**
* Variables assign error
*/
VariablesAssignError("0413", "Variables assign error", "Variables assign error"),
/**
* No matched status
*/
NoMatchedStatus("0414", "No matched status", "No matched status"),
/**
* Asynchronous start disabled
*/
AsynchronousStartDisabled("0415", "Asynchronous start disabled", "Asynchronous start disabled"),
/**
* Operation denied
*/
OperationDenied("0416", "Operation denied", "Operation denied"),
/**
* Context variable replay failed
*/
ContextVariableReplayFailed("0417", "Context variable replay failed", "Context variable replay failed"),
/**
* Context variable replay failed
*/
InvalidParameter("0418", "Invalid parameter", "Invalid parameter"),
/**
* Invoke transaction manager error
*/
TransactionManagerError("0419", "Invoke transaction manager error", "Invoke transaction manager error"),
/**
* State machine instance not exists
*/
StateMachineInstanceNotExists("0420", "State machine instance not exists", "State machine instance not exists"),
/**
* State machine execution timeout
*/
StateMachineExecutionTimeout("0421", "State machine execution timeout", "State machine execution timeout"),
/**
* State machine execution no choice matched
*/
StateMachineNoChoiceMatched("0422", "State machine no choice matched", "State machine no choice matched"),
/**
* Undefined error
*/
UnknownAppError("10000", "Unknown error", "Internal error"),
;
/**
* The Err code.
*/
private String errCode;
/**
* The Err message.
*/
private String errMessage;
/**
* The Err dispose.
*/
private String errDispose;
FrameworkErrorCode(String errCode, String errMessage, String errDispose) {
this.errCode = errCode;
this.errMessage = errMessage;
this.errDispose = errDispose;
}
public String getErrCode() {
return errCode;
}
public String getErrMessage() {
return errMessage;
}
public String getErrDispose() {
return errDispose;
}
@Override
public String toString() {
return String.format("[%s] [%s] [%s]", errCode, errMessage, errDispose);
}
}

View File

@@ -0,0 +1,161 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.exception;
import java.sql.SQLException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The type Framework exception.
*
* @author slievrly
*/
public class FrameworkException extends RuntimeException {
private static final Logger LOGGER = LoggerFactory.getLogger(FrameworkException.class);
private static final long serialVersionUID = 5531074229174745826L;
private final FrameworkErrorCode errcode;
/**
* Instantiates a new Framework exception.
*/
public FrameworkException() {
this(FrameworkErrorCode.UnknownAppError);
}
/**
* Instantiates a new Framework exception.
*
* @param err the err
*/
public FrameworkException(FrameworkErrorCode err) {
this(err.getErrMessage(), err);
}
/**
* Instantiates a new Framework exception.
*
* @param msg the msg
*/
public FrameworkException(String msg) {
this(msg, FrameworkErrorCode.UnknownAppError);
}
/**
* Instantiates a new Framework exception.
*
* @param msg the msg
* @param errCode the err code
*/
public FrameworkException(String msg, FrameworkErrorCode errCode) {
this(null, msg, errCode);
}
/**
* Instantiates a new Framework exception.
*
* @param cause the cause
* @param msg the msg
* @param errCode the err code
*/
public FrameworkException(Throwable cause, String msg, FrameworkErrorCode errCode) {
super(msg, cause);
this.errcode = errCode;
}
/**
* Instantiates a new Framework exception.
*
* @param th the th
*/
public FrameworkException(Throwable th) {
this(th, th.getMessage());
}
/**
* Instantiates a new Framework exception.
*
* @param th the th
* @param msg the msg
*/
public FrameworkException(Throwable th, String msg) {
this(th, msg, FrameworkErrorCode.UnknownAppError);
}
/**
* Gets errcode.
*
* @return the errcode
*/
public FrameworkErrorCode getErrcode() {
return errcode;
}
/**
* Nested exception framework exception.
*
* @param e the e
* @return the framework exception
*/
public static FrameworkException nestedException(Throwable e) {
return nestedException("", e);
}
/**
* Nested exception framework exception.
*
* @param msg the msg
* @param e the e
* @return the framework exception
*/
public static FrameworkException nestedException(String msg, Throwable e) {
LOGGER.error(msg, e.getMessage(), e);
if (e instanceof FrameworkException) {
return (FrameworkException)e;
}
return new FrameworkException(e, msg);
}
/**
* Nested sql exception sql exception.
*
* @param e the e
* @return the sql exception
*/
public static SQLException nestedSQLException(Throwable e) {
return nestedSQLException("", e);
}
/**
* Nested sql exception sql exception.
*
* @param msg the msg
* @param e the e
* @return the sql exception
*/
public static SQLException nestedSQLException(String msg, Throwable e) {
LOGGER.error(msg, e.getMessage(), e);
if (e instanceof SQLException) {
return (SQLException)e;
}
return new SQLException(e);
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.exception;
/**
* The type Not support yet exception.
*
* @author slievrly
*/
public class NotSupportYetException extends RuntimeException {
/**
* Instantiates a new Not support yet exception.
*/
public NotSupportYetException() {
super();
}
/**
* Instantiates a new Not support yet exception.
*
* @param message the message
*/
public NotSupportYetException(String message) {
super(message);
}
/**
* Instantiates a new Not support yet exception.
*
* @param message the message
* @param cause the cause
*/
public NotSupportYetException(String message, Throwable cause) {
super(message, cause);
}
/**
* Instantiates a new Not support yet exception.
*
* @param cause the cause
*/
public NotSupportYetException(Throwable cause) {
super(cause);
}
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.exception;
/**
* The redis operate exception
*
* @author wangzhongxiang
*/
public class RedisException extends FrameworkException {
/**
* Instantiates a new Redis exception.
*/
public RedisException() {
}
/**
* Instantiates a new Redis exception.
*
* @param err the err
*/
public RedisException(FrameworkErrorCode err) {
super(err);
}
/**
* Instantiates a new Redis exception.
*
* @param msg the msg
*/
public RedisException(String msg) {
super(msg);
}
/**
* Instantiates a new Redis exception.
*
* @param msg the msg
* @param errCode the err code
*/
public RedisException(String msg, FrameworkErrorCode errCode) {
super(msg, errCode);
}
/**
* Instantiates a new Redis exception.
*
* @param cause the cause
* @param msg the msg
* @param errCode the err code
*/
public RedisException(Throwable cause, String msg, FrameworkErrorCode errCode) {
super(cause, msg, errCode);
}
/**
* Instantiates a new Redis exception.
*
* @param th the th
*/
public RedisException(Throwable th) {
super(th);
}
/**
* Instantiates a new Redis exception.
*
* @param th the th
* @param msg the msg
*/
public RedisException(Throwable th, String msg) {
super(th, msg);
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.exception;
/**
* The type Should never happen exception.
*
* @author slievrly
*/
public class ShouldNeverHappenException extends RuntimeException {
/**
* Instantiates a new Should never happen exception.
*/
public ShouldNeverHappenException() {
super();
}
/**
* Instantiates a new Should never happen exception.
*
* @param message the message
*/
public ShouldNeverHappenException(String message) {
super(message);
}
/**
* Instantiates a new Should never happen exception.
*
* @param message the message
* @param cause the cause
*/
public ShouldNeverHappenException(String message, Throwable cause) {
super(message, cause);
}
/**
* Instantiates a new Should never happen exception.
*
* @param cause the cause
*/
public ShouldNeverHappenException(Throwable cause) {
super(cause);
}
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.exception;
/**
* the store exception
*
* @author zhangsen
*/
public class StoreException extends FrameworkException {
/**
* Instantiates a new Store exception.
*/
public StoreException() {
}
/**
* Instantiates a new Store exception.
*
* @param err the err
*/
public StoreException(FrameworkErrorCode err) {
super(err);
}
/**
* Instantiates a new Store exception.
*
* @param msg the msg
*/
public StoreException(String msg) {
super(msg);
}
/**
* Instantiates a new Store exception.
*
* @param msg the msg
* @param errCode the err code
*/
public StoreException(String msg, FrameworkErrorCode errCode) {
super(msg, errCode);
}
/**
* Instantiates a new Store exception.
*
* @param cause the cause
* @param msg the msg
* @param errCode the err code
*/
public StoreException(Throwable cause, String msg, FrameworkErrorCode errCode) {
super(cause, msg, errCode);
}
/**
* Instantiates a new Store exception.
*
* @param th the th
*/
public StoreException(Throwable th) {
super(th);
}
/**
* Instantiates a new Store exception.
*
* @param th the th
* @param msg the msg
*/
public StoreException(Throwable th, String msg) {
super(th, msg);
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.executor;
/**
* The interface Callback.
*
* @param <T> the type parameter
*
* @author zhangsen
*/
public interface Callback<T> {
/**
* Execute t.
*
* @return the t
* @throws Throwable the throwable
*/
T execute() throws Throwable;
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.executor;
/**
* The interface Initialize.
*
* @author zhangsen
*/
public interface Initialize {
/**
* init method
*/
void init();
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.holder;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import io.seata.common.exception.ShouldNeverHappenException;
/**
* @author xingfudeshi@gmail.com
* The enum object holder
*/
public enum ObjectHolder {
/**
* singleton instance
*/
INSTANCE;
private static final int MAP_SIZE = 8;
private static final Map<String, Object> OBJECT_MAP = new ConcurrentHashMap<>(MAP_SIZE);
public Object getObject(String objectKey) {
return OBJECT_MAP.get(objectKey);
}
public <T> T getObject(Class<T> clasz) {
return clasz.cast(OBJECT_MAP.values().stream().filter(clasz::isInstance).findAny().orElseThrow(() -> new ShouldNeverHappenException("Can't find any object of class " + clasz.getName())));
}
/**
* Sets object.
*
* @param objectKey the key
* @param object the object
* @return the previous object with the key, or null
*/
public Object setObject(String objectKey, Object object) {
return OBJECT_MAP.putIfAbsent(objectKey, object);
}
}

View File

@@ -0,0 +1,587 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.loader;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;
import io.seata.common.Constants;
import io.seata.common.executor.Initialize;
import io.seata.common.util.CollectionUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The type Enhanced service loader.
*
* @author slievrly
*/
public class EnhancedServiceLoader {
/**
* Specify classLoader to load the service provider
*
* @param <S> the type parameter
* @param service the service
* @param loader the loader
* @return s s
* @throws EnhancedServiceNotFoundException the enhanced service not found exception
*/
public static <S> S load(Class<S> service, ClassLoader loader) throws EnhancedServiceNotFoundException {
return InnerEnhancedServiceLoader.getServiceLoader(service).load(loader);
}
/**
* load service provider
*
* @param <S> the type parameter
* @param service the service
* @return s s
* @throws EnhancedServiceNotFoundException the enhanced service not found exception
*/
public static <S> S load(Class<S> service) throws EnhancedServiceNotFoundException {
return InnerEnhancedServiceLoader.getServiceLoader(service).load(findClassLoader());
}
/**
* load service provider
*
* @param <S> the type parameter
* @param service the service
* @param activateName the activate name
* @return s s
* @throws EnhancedServiceNotFoundException the enhanced service not found exception
*/
public static <S> S load(Class<S> service, String activateName) throws EnhancedServiceNotFoundException {
return InnerEnhancedServiceLoader.getServiceLoader(service).load(activateName, findClassLoader());
}
/**
* Specify classLoader to load the service provider
*
* @param <S> the type parameter
* @param service the service
* @param activateName the activate name
* @param loader the loader
* @return s s
* @throws EnhancedServiceNotFoundException the enhanced service not found exception
*/
public static <S> S load(Class<S> service, String activateName, ClassLoader loader)
throws EnhancedServiceNotFoundException {
return InnerEnhancedServiceLoader.getServiceLoader(service).load(activateName, loader);
}
/**
* Load s.
*
* @param <S> the type parameter
* @param service the service
* @param activateName the activate name
* @param args the args
* @return the s
* @throws EnhancedServiceNotFoundException the enhanced service not found exception
*/
public static <S> S load(Class<S> service, String activateName, Object[] args)
throws EnhancedServiceNotFoundException {
return InnerEnhancedServiceLoader.getServiceLoader(service).load(activateName, args, findClassLoader());
}
/**
* Load s.
*
* @param <S> the type parameter
* @param service the service
* @param activateName the activate name
* @param argsType the args type
* @param args the args
* @return the s
* @throws EnhancedServiceNotFoundException the enhanced service not found exception
*/
public static <S> S load(Class<S> service, String activateName, Class[] argsType, Object[] args)
throws EnhancedServiceNotFoundException {
return InnerEnhancedServiceLoader.getServiceLoader(service).load(activateName, argsType, args, findClassLoader());
}
/**
* get all implements
*
* @param <S> the type parameter
* @param service the service
* @return list list
*/
public static <S> List<S> loadAll(Class<S> service) {
return InnerEnhancedServiceLoader.getServiceLoader(service).loadAll(findClassLoader());
}
/**
* get all implements
*
* @param <S> the type parameter
* @param service the service
* @param argsType the args type
* @param args the args
* @return list list
*/
public static <S> List<S> loadAll(Class<S> service, Class[] argsType, Object[] args) {
return InnerEnhancedServiceLoader.getServiceLoader(service).loadAll(argsType, args, findClassLoader());
}
/**
* Get all the extension classes, follow {@linkplain LoadLevel} defined and sort order
*
* @param <S> the type parameter
* @param service the service
* @return all extension class
*/
@SuppressWarnings("rawtypes")
static <S> List<Class> getAllExtensionClass(Class<S> service) {
return InnerEnhancedServiceLoader.getServiceLoader(service).getAllExtensionClass(findClassLoader());
}
/**
* Get all the extension classes, follow {@linkplain LoadLevel} defined and sort order
*
* @param <S> the type parameter
* @param service the service
* @param loader the loader
* @return all extension class
*/
@SuppressWarnings("rawtypes")
static <S> List<Class> getAllExtensionClass(Class<S> service, ClassLoader loader) {
return InnerEnhancedServiceLoader.getServiceLoader(service).getAllExtensionClass(loader);
}
/**
* Cannot use TCCL, in the pandora container will cause the class in the plugin not to be loaded
*
* @return
*/
private static ClassLoader findClassLoader() {
return EnhancedServiceLoader.class.getClassLoader();
}
private static class InnerEnhancedServiceLoader<S> {
private static final Logger LOGGER = LoggerFactory.getLogger(InnerEnhancedServiceLoader.class);
private static final String SERVICES_DIRECTORY = "META-INF/services/";
private static final String SEATA_DIRECTORY = "META-INF/seata/";
private static final ConcurrentMap<Class<?>, InnerEnhancedServiceLoader<?>> SERVICE_LOADERS =
new ConcurrentHashMap<>();
private final Class<S> type;
private final Holder<List<ExtensionDefinition>> definitionsHolder = new Holder<>();
private final ConcurrentMap<ExtensionDefinition, Holder<Object>> definitionToInstanceMap =
new ConcurrentHashMap<>();
private final ConcurrentMap<String, List<ExtensionDefinition>> nameToDefinitionsMap = new ConcurrentHashMap<>();
private final ConcurrentMap<Class<?>, ExtensionDefinition> classToDefinitionMap = new ConcurrentHashMap<>();
private InnerEnhancedServiceLoader(Class<S> type) {
this.type = type;
}
/**
* Get the ServiceLoader for the specified Class
*
* @param type the type of the extension point
* @param <S> the type
* @return the service loader
*/
private static <S> InnerEnhancedServiceLoader<S> getServiceLoader(Class<S> type) {
if (type == null) {
throw new IllegalArgumentException("Enhanced Service type == null");
}
return (InnerEnhancedServiceLoader<S>)CollectionUtils.computeIfAbsent(SERVICE_LOADERS, type,
key -> new InnerEnhancedServiceLoader<>(type));
}
/**
* Specify classLoader to load the service provider
*
* @param loader the loader
* @return s s
* @throws EnhancedServiceNotFoundException the enhanced service not found exception
*/
private S load(ClassLoader loader) throws EnhancedServiceNotFoundException {
return loadExtension(loader, null, null);
}
/**
* Specify classLoader to load the service provider
*
* @param activateName the activate name
* @param loader the loader
* @return s s
* @throws EnhancedServiceNotFoundException the enhanced service not found exception
*/
private S load(String activateName, ClassLoader loader)
throws EnhancedServiceNotFoundException {
return loadExtension(activateName, loader, null, null);
}
/**
* Load s.
*
* @param activateName the activate name
* @param args the args
* @param loader the loader
* @return the s
* @throws EnhancedServiceNotFoundException the enhanced service not found exception
*/
private S load(String activateName, Object[] args, ClassLoader loader)
throws EnhancedServiceNotFoundException {
Class[] argsType = null;
if (args != null && args.length > 0) {
argsType = new Class[args.length];
for (int i = 0; i < args.length; i++) {
argsType[i] = args[i].getClass();
}
}
return loadExtension(activateName, loader, argsType, args);
}
/**
* Load s.
*
* @param activateName the activate name
* @param argsType the args type
* @param args the args
* @param loader the class loader
* @return the s
* @throws EnhancedServiceNotFoundException the enhanced service not found exception
*/
private S load(String activateName, Class[] argsType, Object[] args, ClassLoader loader)
throws EnhancedServiceNotFoundException {
return loadExtension(activateName, loader, argsType, args);
}
/**
* get all implements
* @param loader the class loader
*
* @return list list
*/
private List<S> loadAll(ClassLoader loader) {
return loadAll(null, null, loader);
}
/**
* get all implements
*
* @param argsType the args type
* @param args the args
* @return list list
*/
private List<S> loadAll(Class[] argsType, Object[] args, ClassLoader loader) {
List<S> allInstances = new ArrayList<>();
List<Class> allClazzs = getAllExtensionClass(loader);
if (CollectionUtils.isEmpty(allClazzs)) {
return allInstances;
}
try {
for (Class clazz : allClazzs) {
ExtensionDefinition definition = classToDefinitionMap.get(clazz);
allInstances.add(getExtensionInstance(definition, loader, argsType, args));
}
} catch (Throwable t) {
throw new EnhancedServiceNotFoundException(t);
}
return allInstances;
}
/**
* Get all the extension classes, follow {@linkplain LoadLevel} defined and sort order
*
* @param loader the loader
* @return all extension class
*/
@SuppressWarnings("rawtypes")
private List<Class> getAllExtensionClass(ClassLoader loader) {
return loadAllExtensionClass(loader);
}
@SuppressWarnings("rawtypes")
private S loadExtension(ClassLoader loader, Class[] argTypes,
Object[] args) {
try {
loadAllExtensionClass(loader);
ExtensionDefinition defaultExtensionDefinition = getDefaultExtensionDefinition();
return getExtensionInstance(defaultExtensionDefinition, loader, argTypes, args);
} catch (Throwable e) {
if (e instanceof EnhancedServiceNotFoundException) {
throw (EnhancedServiceNotFoundException)e;
} else {
throw new EnhancedServiceNotFoundException(
"not found service provider for : " + type.getName() + " caused by " + ExceptionUtils
.getFullStackTrace(e));
}
}
}
@SuppressWarnings("rawtypes")
private S loadExtension(String activateName, ClassLoader loader, Class[] argTypes,
Object[] args) {
if (io.seata.common.util.StringUtils.isEmpty(activateName)) {
throw new IllegalArgumentException("the name of service provider for [" + type.getName() + "] name is null");
}
try {
loadAllExtensionClass(loader);
ExtensionDefinition cachedExtensionDefinition = getCachedExtensionDefinition(activateName);
return getExtensionInstance(cachedExtensionDefinition, loader, argTypes, args);
} catch (Throwable e) {
if (e instanceof EnhancedServiceNotFoundException) {
throw (EnhancedServiceNotFoundException)e;
} else {
throw new EnhancedServiceNotFoundException(
"not found service provider for : " + type.getName() + " caused by " + ExceptionUtils
.getFullStackTrace(e));
}
}
}
private S getExtensionInstance(ExtensionDefinition definition, ClassLoader loader, Class[] argTypes,
Object[] args) {
if (definition == null) {
throw new EnhancedServiceNotFoundException("not found service provider for : " + type.getName());
}
if (Scope.SINGLETON.equals(definition.getScope())) {
Holder<Object> holder = CollectionUtils.computeIfAbsent(definitionToInstanceMap, definition,
key -> new Holder<>());
Object instance = holder.get();
if (instance == null) {
synchronized (holder) {
instance = holder.get();
if (instance == null) {
instance = createNewExtension(definition, loader, argTypes, args);
holder.set(instance);
}
}
}
return (S)instance;
} else {
return createNewExtension(definition, loader, argTypes, args);
}
}
private S createNewExtension(ExtensionDefinition definition, ClassLoader loader, Class[] argTypes, Object[] args) {
Class<?> clazz = definition.getServiceClass();
try {
S newInstance = initInstance(clazz, argTypes, args);
return newInstance;
} catch (Throwable t) {
throw new IllegalStateException("Extension instance(definition: " + definition + ", class: " +
type + ") could not be instantiated: " + t.getMessage(), t);
}
}
private List<Class> loadAllExtensionClass(ClassLoader loader) {
List<ExtensionDefinition> definitions = definitionsHolder.get();
if (definitions == null) {
synchronized (definitionsHolder) {
definitions = definitionsHolder.get();
if (definitions == null) {
definitions = findAllExtensionDefinition(loader);
definitionsHolder.set(definitions);
}
}
}
return definitions.stream().map(def -> def.getServiceClass()).collect(Collectors.toList());
}
@SuppressWarnings("rawtypes")
private List<ExtensionDefinition> findAllExtensionDefinition(ClassLoader loader) {
List<ExtensionDefinition> extensionDefinitions = new ArrayList<>();
try {
loadFile(SERVICES_DIRECTORY, loader, extensionDefinitions);
loadFile(SEATA_DIRECTORY, loader, extensionDefinitions);
} catch (IOException e) {
throw new EnhancedServiceNotFoundException(e);
}
//After loaded all the extensions,sort the caches by order
if (!nameToDefinitionsMap.isEmpty()) {
for (List<ExtensionDefinition> definitions : nameToDefinitionsMap.values()) {
Collections.sort(definitions, (def1, def2) -> {
int o1 = def1.getOrder();
int o2 = def2.getOrder();
return Integer.compare(o1, o2);
});
}
}
if (!extensionDefinitions.isEmpty()) {
Collections.sort(extensionDefinitions, (definition1, definition2) -> {
int o1 = definition1.getOrder();
int o2 = definition2.getOrder();
return Integer.compare(o1, o2);
});
}
return extensionDefinitions;
}
@SuppressWarnings("rawtypes")
private void loadFile(String dir, ClassLoader loader, List<ExtensionDefinition> extensions)
throws IOException {
String fileName = dir + type.getName();
Enumeration<java.net.URL> urls;
if (loader != null) {
urls = loader.getResources(fileName);
} else {
urls = ClassLoader.getSystemResources(fileName);
}
if (urls != null) {
while (urls.hasMoreElements()) {
java.net.URL url = urls.nextElement();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), Constants.DEFAULT_CHARSET))) {
String line;
while ((line = reader.readLine()) != null) {
final int ci = line.indexOf('#');
if (ci >= 0) {
line = line.substring(0, ci);
}
line = line.trim();
if (line.length() > 0) {
try {
ExtensionDefinition extensionDefinition = getUnloadedExtensionDefinition(line, loader);
if (extensionDefinition == null) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("The same extension {} has already been loaded, skipped", line);
}
continue;
}
extensions.add(extensionDefinition);
} catch (LinkageError | ClassNotFoundException e) {
LOGGER.warn("Load [{}] class fail. {}", line, e.getMessage());
}
}
}
} catch (Throwable e) {
LOGGER.warn("load clazz instance error: {}", e.getMessage());
}
}
}
}
private ExtensionDefinition getUnloadedExtensionDefinition(String className, ClassLoader loader)
throws ClassNotFoundException {
//Check whether the definition has been loaded
if (!isDefinitionContainsClazz(className, loader)) {
Class<?> clazz = Class.forName(className, true, loader);
String serviceName = null;
Integer priority = 0;
Scope scope = Scope.SINGLETON;
LoadLevel loadLevel = clazz.getAnnotation(LoadLevel.class);
if (loadLevel != null) {
serviceName = loadLevel.name();
priority = loadLevel.order();
scope = loadLevel.scope();
}
ExtensionDefinition result = new ExtensionDefinition(serviceName, priority, scope, clazz);
classToDefinitionMap.put(clazz, result);
if (serviceName != null) {
CollectionUtils.computeIfAbsent(nameToDefinitionsMap, serviceName, e -> new ArrayList<>())
.add(result);
}
return result;
}
return null;
}
private boolean isDefinitionContainsClazz(String className, ClassLoader loader) {
for (Map.Entry<Class<?>, ExtensionDefinition> entry : classToDefinitionMap.entrySet()) {
if (!entry.getKey().getName().equals(className)) {
continue;
}
if (Objects.equals(entry.getValue().getServiceClass().getClassLoader(), loader)) {
return true;
}
}
return false;
}
private ExtensionDefinition getDefaultExtensionDefinition() {
List<ExtensionDefinition> currentDefinitions = definitionsHolder.get();
return CollectionUtils.getLast(currentDefinitions);
}
private ExtensionDefinition getCachedExtensionDefinition(String activateName) {
List<ExtensionDefinition> definitions = nameToDefinitionsMap.get(activateName);
return CollectionUtils.getLast(definitions);
}
/**
* init instance
*
* @param implClazz the impl clazz
* @param argTypes the arg types
* @param args the args
* @return s s
* @throws IllegalAccessException the illegal access exception
* @throws InstantiationException the instantiation exception
* @throws NoSuchMethodException the no such method exception
* @throws InvocationTargetException the invocation target exception
*/
private S initInstance(Class implClazz, Class[] argTypes, Object[] args)
throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
S s = null;
if (argTypes != null && args != null) {
// Constructor with arguments
Constructor<S> constructor = implClazz.getDeclaredConstructor(argTypes);
s = type.cast(constructor.newInstance(args));
} else {
// default Constructor
s = type.cast(implClazz.newInstance());
}
if (s instanceof Initialize) {
((Initialize)s).init();
}
return s;
}
/**
* Helper Class for hold a value.
* @param <T>
*/
private static class Holder<T> {
private volatile T value;
private void set(T value) {
this.value = value;
}
private T get() {
return value;
}
}
}
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.loader;
import org.apache.commons.lang.exception.NestableRuntimeException;
/**
* The type Enhanced service not found exception.
*
* @author slievrly
*/
public class EnhancedServiceNotFoundException extends NestableRuntimeException {
private static final long serialVersionUID = 7748438218914409019L;
/**
* Instantiates a new Enhanced service not found exception.
*
* @param errorCode the error code
*/
public EnhancedServiceNotFoundException(String errorCode) {
super(errorCode);
}
/**
* Instantiates a new Enhanced service not found exception.
*
* @param errorCode the error code
* @param cause the cause
*/
public EnhancedServiceNotFoundException(String errorCode, Throwable cause) {
super(errorCode, cause);
}
/**
* Instantiates a new Enhanced service not found exception.
*
* @param errorCode the error code
* @param errorDesc the error desc
*/
public EnhancedServiceNotFoundException(String errorCode, String errorDesc) {
super(errorCode + ":" + errorDesc);
}
/**
* Instantiates a new Enhanced service not found exception.
*
* @param errorCode the error code
* @param errorDesc the error desc
* @param cause the cause
*/
public EnhancedServiceNotFoundException(String errorCode, String errorDesc, Throwable cause) {
super(errorCode + ":" + errorDesc, cause);
}
/**
* Instantiates a new Enhanced service not found exception.
*
* @param cause the cause
*/
public EnhancedServiceNotFoundException(Throwable cause) {
super(cause);
}
@Override
public Throwable fillInStackTrace() {
return this;
}
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.loader;
import io.seata.common.util.StringUtils;
/**
* The type ExtensionDefinition
*
* @author haozhibei
*/
final class ExtensionDefinition {
private String name;
private Class serviceClass;
private Integer order;
private Scope scope;
public Integer getOrder() {
return this.order;
}
public Class getServiceClass() {
return this.serviceClass;
}
public Scope getScope() {
return this.scope;
}
public ExtensionDefinition(String name, Integer order, Scope scope, Class clazz) {
this.name = name;
this.order = order;
this.scope = scope;
this.serviceClass = clazz;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((serviceClass == null) ? 0 : serviceClass.hashCode());
result = prime * result + ((order == null) ? 0 : order.hashCode());
result = prime * result + ((scope == null) ? 0 : scope.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
ExtensionDefinition other = (ExtensionDefinition)obj;
if (!StringUtils.equals(name, other.name)) {
return false;
}
if (!serviceClass.equals(other.serviceClass)) {
return false;
}
if (!order.equals(other.order)) {
return false;
}
return !scope.equals(other.scope);
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.loader;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* The interface Load level.
*
* @author slievrly
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface LoadLevel {
/**
* Name string.
*
* @return the string
*/
String name();
/**
* Order int.
*
* @return the int
*/
int order() default 0;
/**
* Scope enum.
* @return
*/
Scope scope() default Scope.SINGLETON;
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.loader;
/**
* the scope of the extension
*
* @author haozhibei
*/
public enum Scope {
/**
* The extension will be loaded in singleton mode
*/
SINGLETON,
/**
* The extension will be loaded in multi instance mode
*/
PROTOTYPE
}

View File

@@ -0,0 +1,93 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.rpc;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;
/**
* The state statistics.
*
* @author ph3636
*/
public class RpcStatus {
private static final ConcurrentMap<String, RpcStatus> SERVICE_STATUS_MAP = new ConcurrentHashMap<>();
private final AtomicLong active = new AtomicLong();
private final LongAdder total = new LongAdder();
private RpcStatus() {
}
/**
* get the RpcStatus of this service
*
* @param service the service
* @return RpcStatus
*/
public static RpcStatus getStatus(String service) {
return SERVICE_STATUS_MAP.computeIfAbsent(service, key -> new RpcStatus());
}
/**
* remove the RpcStatus of this service
*
* @param service the service
*/
public static void removeStatus(String service) {
SERVICE_STATUS_MAP.remove(service);
}
/**
* begin count
*
* @param service the service
*/
public static void beginCount(String service) {
getStatus(service).active.incrementAndGet();
}
/**
* end count
*
* @param service the service
*/
public static void endCount(String service) {
RpcStatus rpcStatus = getStatus(service);
rpcStatus.active.decrementAndGet();
rpcStatus.total.increment();
}
/**
* get active.
*
* @return active
*/
public long getActive() {
return active.get();
}
/**
* get total.
*
* @return total
*/
public long getTotal() {
return total.longValue();
}
}

View File

@@ -0,0 +1,91 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.thread;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
import io.netty.util.concurrent.FastThreadLocalThread;
import io.seata.common.util.CollectionUtils;
/**
* The type Named thread factory.
*
* @author slievrly
* @author ggndnn
*/
public class NamedThreadFactory implements ThreadFactory {
private final static Map<String, AtomicInteger> PREFIX_COUNTER = new ConcurrentHashMap<>();
private final ThreadGroup group;
private final AtomicInteger counter = new AtomicInteger(0);
private final String prefix;
private final int totalSize;
private final boolean makeDaemons;
/**
* Instantiates a new Named thread factory.
*
* @param prefix the prefix
* @param totalSize the total size
* @param makeDaemons the make daemons
*/
public NamedThreadFactory(String prefix, int totalSize, boolean makeDaemons) {
int prefixCounter = CollectionUtils.computeIfAbsent(PREFIX_COUNTER, prefix, key -> new AtomicInteger(0))
.incrementAndGet();
SecurityManager securityManager = System.getSecurityManager();
group = (securityManager != null) ? securityManager.getThreadGroup() : Thread.currentThread().getThreadGroup();
this.prefix = prefix + "_" + prefixCounter;
this.makeDaemons = makeDaemons;
this.totalSize = totalSize;
}
/**
* Instantiates a new Named thread factory.
*
* @param prefix the prefix
* @param makeDaemons the make daemons
*/
public NamedThreadFactory(String prefix, boolean makeDaemons) {
this(prefix, 0, makeDaemons);
}
/**
* Instantiates a new Named thread factory.
*
* @param prefix the prefix
* @param totalSize the total size
*/
public NamedThreadFactory(String prefix, int totalSize) {
this(prefix, totalSize, true);
}
@Override
public Thread newThread(Runnable r) {
String name = prefix + "_" + counter.incrementAndGet();
if (totalSize > 1) {
name += "_" + totalSize;
}
Thread thread = new FastThreadLocalThread(group, r, name);
thread.setDaemon(makeDaemons);
if (thread.getPriority() != Thread.NORM_PRIORITY) {
thread.setPriority(Thread.NORM_PRIORITY);
}
return thread;
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.thread;
import java.util.concurrent.atomic.AtomicInteger;
/**
* positive atomic counter, begin with 0, ensure the number is positive.
*
* @author Geng Zhang
*/
public class PositiveAtomicCounter {
private static final int MASK = 0x7FFFFFFF;
private final AtomicInteger atom;
public PositiveAtomicCounter() {
atom = new AtomicInteger(0);
}
public final int incrementAndGet() {
return atom.incrementAndGet() & MASK;
}
public final int getAndIncrement() {
return atom.getAndIncrement() & MASK;
}
public int get() {
return atom.get() & MASK;
}
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.thread;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
/**
* Policies for RejectedExecutionHandler
*
* @author guoyao
*/
public final class RejectedPolicies {
/**
* when rejected happened ,add the new task and run the oldest task
*
* @return rejected execution handler
*/
public static RejectedExecutionHandler runsOldestTaskPolicy() {
return (r, executor) -> {
if (executor.isShutdown()) {
return;
}
BlockingQueue<Runnable> workQueue = executor.getQueue();
Runnable firstWork = workQueue.poll();
boolean newTaskAdd = workQueue.offer(r);
if (firstWork != null) {
firstWork.run();
}
if (!newTaskAdd) {
executor.execute(r);
}
};
}
}

View File

@@ -0,0 +1,154 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
import io.seata.common.exception.NotSupportYetException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The bean utils
*
* @author wangzhongxiang
*/
public class BeanUtils {
protected static final Logger LOGGER = LoggerFactory.getLogger(BeanUtils.class);
public static String beanToString(Object o) {
if (o == null) {
return null;
}
Field[] fields = o.getClass().getDeclaredFields();
StringBuilder buffer = new StringBuilder();
buffer.append("[");
for (Field field : fields) {
Object val = null;
try {
val = ReflectionUtil.getFieldValue(o, field.getName());
} catch (NoSuchFieldException e) {
LOGGER.warn(e.getMessage(), e);
} catch (IllegalAccessException e) {
LOGGER.warn(e.getMessage(), e);
}
if (val != null) {
buffer.append(field.getName()).append("=").append(val).append(", ");
}
}
if (buffer.length() > 2) {
buffer.delete(buffer.length() - 2, buffer.length());
}
buffer.append("]");
return buffer.toString();
}
/**
* map to object
*
* @param map the map
* @param clazz the Object class
* @return the object
*/
public static Object mapToObject(Map<String, String> map, Class<?> clazz) {
if (CollectionUtils.isEmpty(map)) {
return null;
}
try {
Object instance = clazz.newInstance();
Field[] fields = instance.getClass().getDeclaredFields();
for (Field field : fields) {
int modifiers = field.getModifiers();
if (Modifier.isStatic(modifiers) || Modifier.isFinal(modifiers)) {
continue;
}
boolean accessible = field.isAccessible();
field.setAccessible(true);
Class<?> type = field.getType();
if (type == Date.class) {
if (!StringUtils.isEmpty(map.get(field.getName()))) {
field.set(instance, new Date(Long.valueOf(map.get(field.getName()))));
}
} else if (type == Long.class) {
if (!StringUtils.isEmpty(map.get(field.getName()))) {
field.set(instance, Long.valueOf(map.get(field.getName())));
}
} else if (type == Integer.class) {
if (!StringUtils.isEmpty(map.get(field.getName()))) {
field.set(instance, Integer.valueOf(map.get(field.getName())));
}
} else if (type == Double.class) {
if (!StringUtils.isEmpty(map.get(field.getName()))) {
field.set(instance, Double.valueOf(map.get(field.getName())));
}
} else if (type == String.class) {
if (!StringUtils.isEmpty(map.get(field.getName()))) {
field.set(instance, map.get(field.getName()));
}
}
field.setAccessible(accessible);
}
return instance;
} catch (IllegalAccessException e) {
throw new NotSupportYetException(
"map to " + clazz.toString() + " failed:" + e.getMessage(), e);
} catch (InstantiationException e) {
throw new NotSupportYetException(
"map to " + clazz.toString() + " failed:" + e.getMessage(), e);
}
}
/**
* object to map
*
* @param object the object
* @return the map
*/
public static Map<String, String> objectToMap(Object object) {
if (object == null) {
return null;
}
Map<String, String> map = new HashMap<>(16);
Field[] fields = object.getClass().getDeclaredFields();
try {
for (Field field : fields) {
boolean accessible = field.isAccessible();
field.setAccessible(true);
if (field.getType() == Date.class) {
Date date = (Date) field.get(object);
if (date != null) {
map.put(field.getName(), String.valueOf(date.getTime()));
}
} else {
map.put(field.getName(),
field.get(object) == null ? "" : field.get(object).toString());
}
field.setAccessible(accessible);
}
} catch (IllegalAccessException e) {
throw new NotSupportYetException(
"object " + object.getClass().toString() + " to map failed:" + e.getMessage());
}
return map;
}
}

View File

@@ -0,0 +1,108 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
import java.sql.Blob;
import javax.sql.rowset.serial.SerialBlob;
import io.seata.common.Constants;
import io.seata.common.exception.ShouldNeverHappenException;
/**
* The type Blob utils.
*
* @author slievrly
* @author Geng Zhang
*/
public class BlobUtils {
private BlobUtils() {
}
/**
* String 2 blob blob.
*
* @param str the str
* @return the blob
*/
public static Blob string2blob(String str) {
if (str == null) {
return null;
}
try {
return new SerialBlob(str.getBytes(Constants.DEFAULT_CHARSET));
} catch (Exception e) {
throw new ShouldNeverHappenException(e);
}
}
/**
* Blob 2 string string.
*
* @param blob the blob
* @return the string
*/
public static String blob2string(Blob blob) {
if (blob == null) {
return null;
}
try {
return new String(blob.getBytes((long) 1, (int) blob.length()), Constants.DEFAULT_CHARSET);
} catch (Exception e) {
throw new ShouldNeverHappenException(e);
}
}
/**
* Byte array to blob
*
* @param bytes the byte array
* @return the blob
*/
public static Blob bytes2Blob(byte[] bytes) {
if (bytes == null) {
return null;
}
try {
return new SerialBlob(bytes);
} catch (Exception e) {
throw new ShouldNeverHappenException(e);
}
}
/**
* Blob to byte array.
*
* @param blob the blob
* @return the byte array
*/
public static byte[] blob2Bytes(Blob blob) {
if (blob == null) {
return null;
}
try {
return blob.getBytes((long) 1, (int) blob.length());
} catch (Exception e) {
throw new ShouldNeverHappenException(e);
}
}
}

View File

@@ -0,0 +1,280 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
/**
* The type Collection utils.
*
* @author zhangsen
* @author Geng Zhang
*/
public class CollectionUtils {
private CollectionUtils() {
}
/**
* Is empty boolean.
*
* @param col the col
* @return the boolean
*/
public static boolean isEmpty(Collection<?> col) {
return !isNotEmpty(col);
}
/**
* Is not empty boolean.
*
* @param col the col
* @return the boolean
*/
public static boolean isNotEmpty(Collection<?> col) {
return col != null && !col.isEmpty();
}
/**
* Is empty boolean.
*
* @param array the array
* @return the boolean
*/
public static boolean isEmpty(Object[] array) {
return !isNotEmpty(array);
}
/**
* Is not empty boolean.
*
* @param array the array
* @return the boolean
*/
public static boolean isNotEmpty(Object[] array) {
return array != null && array.length > 0;
}
/**
* Is empty boolean.
*
* @param map the map
* @return the boolean
*/
public static boolean isEmpty(Map<?, ?> map) {
return !isNotEmpty(map);
}
/**
* Is not empty boolean.
*
* @param map the map
* @return the boolean
*/
public static boolean isNotEmpty(Map<?, ?> map) {
return map != null && !map.isEmpty();
}
/**
* To string.
*
* @param col the col
* @return the string
*/
public static String toString(Collection<?> col) {
if (isEmpty(col)) {
return "";
}
StringBuilder sb = new StringBuilder();
sb.append("[");
for (Object obj : col) {
sb.append(StringUtils.toString(obj));
sb.append(",");
}
sb.deleteCharAt(sb.length() - 1);
sb.append("]");
return sb.toString();
}
/**
* To string map
*
* @param param map
* @return the string map
*/
public static Map<String, String> toStringMap(Map<String, Object> param) {
Map<String, String> covertMap = new HashMap<>();
if (CollectionUtils.isNotEmpty(param)) {
param.forEach((key, value) -> {
if (value != null) {
covertMap.put(key, StringUtils.toString(value));
}
});
}
return covertMap;
}
/**
* Is size equals boolean.
*
* @param col0 the col 0
* @param col1 the col 1
* @return the boolean
*/
public static boolean isSizeEquals(Collection<?> col0, Collection<?> col1) {
if (col0 == null) {
return col1 == null;
} else {
if (col1 == null) {
return false;
} else {
return col0.size() == col1.size();
}
}
}
private static final String KV_SPLIT = "=";
private static final String PAIR_SPLIT = "&";
/**
* Encode map to string
*
* @param map origin map
* @return String string
*/
public static String encodeMap(Map<String, String> map) {
if (map == null) {
return null;
}
if (map.isEmpty()) {
return StringUtils.EMPTY;
}
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : map.entrySet()) {
sb.append(entry.getKey()).append(KV_SPLIT).append(entry.getValue()).append(PAIR_SPLIT);
}
return sb.substring(0, sb.length() - 1);
}
/**
* Decode string to map
*
* @param data data
* @return map map
*/
public static Map<String, String> decodeMap(String data) {
if (data == null) {
return null;
}
Map<String, String> map = new HashMap<>();
if (StringUtils.isBlank(data)) {
return map;
}
String[] kvPairs = data.split(PAIR_SPLIT);
if (kvPairs.length == 0) {
return map;
}
for (String kvPair : kvPairs) {
if (StringUtils.isNullOrEmpty(kvPair)) {
continue;
}
String[] kvs = kvPair.split(KV_SPLIT);
if (kvs.length != 2) {
continue;
}
map.put(kvs[0], kvs[1]);
}
return map;
}
/**
* Compute if absent.
* Use this method if you are frequently using the same key,
* because the get method has no lock.
*
* @param map the map
* @param key the key
* @param mappingFunction the mapping function
* @param <K> the type of key
* @param <V> the type of value
* @return the value
*/
public static <K, V> V computeIfAbsent(Map<K, V> map, K key, Function<? super K, ? extends V> mappingFunction) {
V value = map.get(key);
if (value != null) {
return value;
}
return map.computeIfAbsent(key, mappingFunction);
}
/**
* To upper list list.
*
* @param sourceList the source list
* @return the list
*/
public static List<String> toUpperList(List<String> sourceList) {
if (isEmpty(sourceList)) {
return sourceList;
}
List<String> destList = new ArrayList<>(sourceList.size());
for (String element : sourceList) {
if (element != null) {
destList.add(element.toUpperCase());
} else {
destList.add(null);
}
}
return destList;
}
/**
* Get the last item.
* <p>
* 'IndexOutOfBoundsException' may be thrown, because the `list.size()` and `list.get(size - 1)` are not atomic.
* This method can avoid the 'IndexOutOfBoundsException' cause by concurrency.
* </p>
*
* @param list the list
* @param <T> the type of item
* @return the last item
*/
public static <T> T getLast(List<T> list) {
if (isEmpty(list)) {
return null;
}
int size;
while (true) {
size = list.size();
if (size == 0) {
return null;
}
try {
return list.get(size - 1);
} catch (IndexOutOfBoundsException ex) {
// catch the exception and continue to retry
}
}
}
}

View File

@@ -0,0 +1,93 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
/**
* The type Compress util.
*/
public class CompressUtil {
/**
* Compress byte [ ].
*
* @param src the src
* @return the byte [ ]
* @throws IOException the io exception
*/
public static byte[] compress(final byte[] src) throws IOException {
byte[] result;
ByteArrayOutputStream bos = new ByteArrayOutputStream(src.length);
GZIPOutputStream gos = new GZIPOutputStream(bos);
try {
gos.write(src);
gos.finish();
result = bos.toByteArray();
} finally {
IOUtil.close(bos, gos);
}
return result;
}
/**
* Uncompress byte [ ].
*
* @param src the src
* @return the byte [ ]
* @throws IOException the io exception
*/
public static byte[] uncompress(final byte[] src) throws IOException {
byte[] result;
byte[] uncompressData = new byte[src.length];
ByteArrayInputStream bis = new ByteArrayInputStream(src);
GZIPInputStream iis = new GZIPInputStream(bis);
ByteArrayOutputStream bos = new ByteArrayOutputStream(src.length);
try {
while (true) {
int len = iis.read(uncompressData, 0, uncompressData.length);
if (len <= 0) {
break;
}
bos.write(uncompressData, 0, len);
}
bos.flush();
result = bos.toByteArray();
} finally {
IOUtil.close(bis, iis, bos);
}
return result;
}
/**
* Is compress data boolean.
*
* @param bytes the bytes
* @return the boolean
*/
public static boolean isCompressData(byte[] bytes) {
if (bytes != null && bytes.length > 2) {
int header = ((bytes[0] & 0xff)) | (bytes[1] & 0xff) << 8;
return GZIPInputStream.GZIP_MAGIC == header;
}
return false;
}
}

View File

@@ -0,0 +1,142 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Scanner;
import javax.crypto.Cipher;
/**
* @author funkye
*/
public class ConfigTools {
// generate key pair
public static KeyPair getKeyPair() throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
return keyPair;
}
// obtain the public key (Base64 encoding)
public static String getPublicKey(KeyPair keyPair) {
PublicKey publicKey = keyPair.getPublic();
byte[] bytes = publicKey.getEncoded();
return byte2Base64(bytes);
}
// obtain the private key (Base64 encoding)
public static String getPrivateKey(KeyPair keyPair) {
PrivateKey privateKey = keyPair.getPrivate();
byte[] bytes = privateKey.getEncoded();
return byte2Base64(bytes);
}
// convert Base64 encoded public key to PublicKey object
public static PublicKey string2PublicKey(String pubStr) throws Exception {
byte[] keyBytes = base642Byte(pubStr);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
}
// convert Base64 encoded private key to PrivateKey object
public static PrivateKey string2PrivateKey(String priStr) throws Exception {
byte[] keyBytes = base642Byte(priStr);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}
// public key encryption
public static String publicEncrypt(String content, String pubStr) throws Exception {
PublicKey publicKey = string2PublicKey(pubStr);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] bytes = cipher.doFinal(content.getBytes());
return byte2Base64(bytes);
}
// public key decryption
public static String publicDecrypt(String content, String pubStr) throws Exception {
PublicKey publicKey = string2PublicKey(pubStr);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, publicKey);
byte[] bytes = cipher.doFinal(base642Byte(content));
return new String(bytes, StandardCharsets.UTF_8);
}
// private key encryption
public static String privateEncrypt(String content, String priStr) throws Exception {
PrivateKey privateKey = string2PrivateKey(priStr);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] bytes = cipher.doFinal(content.getBytes());
return byte2Base64(bytes);
}
// private key decryption
public static String privateDecrypt(String content, String priStr) throws Exception {
PrivateKey privateKey = string2PrivateKey(priStr);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] bytes = cipher.doFinal(base642Byte(content));
return new String(bytes, StandardCharsets.UTF_8);
}
// byte array to Base64 encoding
public static String byte2Base64(byte[] bytes) {
return new String(Base64.getEncoder().encode(bytes), StandardCharsets.UTF_8);
}
// Base64 encoding to byte array
public static byte[] base642Byte(String base64Key) {
return Base64.getDecoder().decode(base64Key);
}
public static void main(String[] args) throws Exception {
Scanner scan = new Scanner(System.in);
KeyPair keyPair = getKeyPair();
String publicKeyStr = ConfigTools.getPublicKey(keyPair);
String privateKeyStr = ConfigTools.getPrivateKey(keyPair);
System.out.println("publicKeyStr:\n" + publicKeyStr);
System.out.println("privateKeyStr:\n" + privateKeyStr);
System.out.println(
"after the key is generated, please keep your key pair properly, if you need to encrypt, please enter your database password");
System.out.println("input 'q' exit");
while (scan.hasNextLine()) {
String password = scan.nextLine();
if (StringUtils.isNotBlank(password) && !"q".equalsIgnoreCase(password)) {
String byte2Base64 = ConfigTools.privateEncrypt(password, privateKeyStr);
System.out.println("encryption completed: \n" + byte2Base64);
}
break;
}
scan.close();
}
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
import java.time.Duration;
/**
* @author XCXCXCXCX
*/
public class DurationUtil {
public static final Duration DEFAULT_DURATION = Duration.ofMillis(-1);
public static final String DAY_UNIT = "d";
public static final String HOUR_UNIT = "h";
public static final String MINUTE_UNIT = "m";
public static final String SECOND_UNIT = "s";
public static final String MILLIS_SECOND_UNIT = "ms";
public static Duration parse(String str) {
if (StringUtils.isBlank(str)) {
return DEFAULT_DURATION;
}
if (str.contains(MILLIS_SECOND_UNIT)) {
Long value = doParse(MILLIS_SECOND_UNIT, str);
return value == null ? null : Duration.ofMillis(value);
} else if (str.contains(DAY_UNIT)) {
Long value = doParse(DAY_UNIT, str);
return value == null ? null : Duration.ofDays(value);
} else if (str.contains(HOUR_UNIT)) {
Long value = doParse(HOUR_UNIT, str);
return value == null ? null : Duration.ofHours(value);
} else if (str.contains(MINUTE_UNIT)) {
Long value = doParse(MINUTE_UNIT, str);
return value == null ? null : Duration.ofMinutes(value);
} else if (str.contains(SECOND_UNIT)) {
Long value = doParse(SECOND_UNIT, str);
return value == null ? null : Duration.ofSeconds(value);
}
try {
int millis = Integer.parseInt(str);
return Duration.ofMillis(millis);
} catch (Exception e) {
throw new UnsupportedOperationException(str + " can't parse to duration", e);
}
}
private static Long doParse(String unit, String str) {
str = str.replace(unit, "");
if ("".equals(str)) {
return null;
}
try {
return Long.parseLong(str);
} catch (NumberFormatException e) {
throw new UnsupportedOperationException("\"" + str + "\" can't parse to Duration", e);
}
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
/**
* @author jsbxyyx
*/
public class IOUtil {
/**
* close Closeable
* @param closeables the closeables
*/
public static void close(AutoCloseable... closeables) {
if (CollectionUtils.isNotEmpty(closeables)) {
for (AutoCloseable closeable : closeables) {
close(closeable);
}
}
}
/**
* close Closeable
* @param closeable the closeable
*/
public static void close(AutoCloseable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (Exception ignore) {
}
}
}
}

View File

@@ -0,0 +1,187 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;
/**
* @author funkye
* @author selfishlover
*/
public class IdWorker {
/**
* Start time cut (2020-05-03)
*/
private final long twepoch = 1588435200000L;
/**
* The number of bits occupied by workerId
*/
private final int workerIdBits = 10;
/**
* The number of bits occupied by timestamp
*/
private final int timestampBits = 41;
/**
* The number of bits occupied by sequence
*/
private final int sequenceBits = 12;
/**
* Maximum supported machine id, the result is 1023
*/
private final int maxWorkerId = ~(-1 << workerIdBits);
/**
* business meaning: machine ID (0 ~ 1023)
* actual layout in memory:
* highest 1 bit: 0
* middle 10 bit: workerId
* lowest 53 bit: all 0
*/
private long workerId;
/**
* timestamp and sequence mix in one Long
* highest 11 bit: not used
* middle 41 bit: timestamp
* lowest 12 bit: sequence
*/
private AtomicLong timestampAndSequence;
/**
* mask that help to extract timestamp and sequence from a long
*/
private final long timestampAndSequenceMask = ~(-1L << (timestampBits + sequenceBits));
/**
* instantiate an IdWorker using given workerId
* @param workerId if null, then will auto assign one
*/
public IdWorker(Long workerId) {
initTimestampAndSequence();
initWorkerId(workerId);
}
/**
* init first timestamp and sequence immediately
*/
private void initTimestampAndSequence() {
long timestamp = getNewestTimestamp();
long timestampWithSequence = timestamp << sequenceBits;
this.timestampAndSequence = new AtomicLong(timestampWithSequence);
}
/**
* init workerId
* @param workerId if null, then auto generate one
*/
private void initWorkerId(Long workerId) {
if (workerId == null) {
workerId = generateWorkerId();
}
if (workerId > maxWorkerId || workerId < 0) {
String message = String.format("worker Id can't be greater than %d or less than 0", maxWorkerId);
throw new IllegalArgumentException(message);
}
this.workerId = workerId << (timestampBits + sequenceBits);
}
/**
* get next UUID(base on snowflake algorithm), which look like:
* highest 1 bit: always 0
* next 10 bit: workerId
* next 41 bit: timestamp
* lowest 12 bit: sequence
* @return UUID
*/
public long nextId() {
waitIfNecessary();
long next = timestampAndSequence.incrementAndGet();
long timestampWithSequence = next & timestampAndSequenceMask;
return workerId | timestampWithSequence;
}
/**
* block current thread if the QPS of acquiring UUID is too high
* that current sequence space is exhausted
*/
private void waitIfNecessary() {
long currentWithSequence = timestampAndSequence.get();
long current = currentWithSequence >>> sequenceBits;
long newest = getNewestTimestamp();
if (current >= newest) {
try {
Thread.sleep(5);
} catch (InterruptedException ignore) {
// don't care
}
}
}
/**
* get newest timestamp relative to twepoch
*/
private long getNewestTimestamp() {
return System.currentTimeMillis() - twepoch;
}
/**
* auto generate workerId, try using mac first, if failed, then randomly generate one
* @return workerId
*/
private long generateWorkerId() {
try {
return generateWorkerIdBaseOnMac();
} catch (Exception e) {
return generateRandomWorkerId();
}
}
/**
* use lowest 10 bit of available MAC as workerId
* @return workerId
* @throws Exception when there is no available mac found
*/
private long generateWorkerIdBaseOnMac() throws Exception {
Enumeration<NetworkInterface> all = NetworkInterface.getNetworkInterfaces();
while (all.hasMoreElements()) {
NetworkInterface networkInterface = all.nextElement();
boolean isLoopback = networkInterface.isLoopback();
boolean isVirtual = networkInterface.isVirtual();
if (isLoopback || isVirtual) {
continue;
}
byte[] mac = networkInterface.getHardwareAddress();
return ((mac[4] & 0B11) << 8) | (mac[5] & 0xFF);
}
throw new RuntimeException("no available mac found");
}
/**
* randomly generate one as workerId
* @return workerId
*/
private long generateRandomWorkerId() {
return new Random().nextInt(maxWorkerId + 1);
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
/**
* The type Lambda util.
*
* @author zjinlei
*/
public class LambdaUtils {
public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
Map<Object, Boolean> seen = new ConcurrentHashMap<>();
return object -> seen.putIfAbsent(keyExtractor.apply(object), Boolean.TRUE) == null;
}
}

View File

@@ -0,0 +1,250 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.regex.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The type Net util.
*
* @author slievrly
*/
public class NetUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(NetUtil.class);
private static final String LOCALHOST = "127.0.0.1";
private static final String ANY_HOST = "0.0.0.0";
private static volatile InetAddress LOCAL_ADDRESS = null;
private static final Pattern IP_PATTERN = Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3,5}$");
/**
* To string address string.
*
* @param address the address
* @return the string
*/
public static String toStringAddress(SocketAddress address) {
if (address == null) {
return StringUtils.EMPTY;
}
return toStringAddress((InetSocketAddress) address);
}
/**
* To ip address string.
*
* @param address the address
* @return the string
*/
public static String toIpAddress(SocketAddress address) {
InetSocketAddress inetSocketAddress = (InetSocketAddress) address;
return inetSocketAddress.getAddress().getHostAddress();
}
/**
* To string address string.
*
* @param address the address
* @return the string
*/
public static String toStringAddress(InetSocketAddress address) {
return address.getAddress().getHostAddress() + ":" + address.getPort();
}
/**
* To inet socket address inet socket address.
*
* @param address the address
* @return the inet socket address
*/
public static InetSocketAddress toInetSocketAddress(String address) {
int i = address.indexOf(':');
String host;
int port;
if (i > -1) {
host = address.substring(0, i);
port = Integer.parseInt(address.substring(i + 1));
} else {
host = address;
port = 0;
}
return new InetSocketAddress(host, port);
}
/**
* To long long.
*
* @param address the address
* @return the long
*/
public static long toLong(String address) {
InetSocketAddress ad = toInetSocketAddress(address);
String[] ip = ad.getAddress().getHostAddress().split("\\.");
long r = 0;
r = r | (Long.parseLong(ip[0]) << 40);
r = r | (Long.parseLong(ip[1]) << 32);
r = r | (Long.parseLong(ip[2]) << 24);
r = r | (Long.parseLong(ip[3]) << 16);
r = r | ad.getPort();
return r;
}
/**
* Gets local ip.
*
* @return the local ip
*/
public static String getLocalIp() {
InetAddress address = getLocalAddress();
return address == null ? LOCALHOST : address.getHostAddress();
}
/**
* Gets local host.
*
* @return the local host
*/
public static String getLocalHost() {
InetAddress address = getLocalAddress();
return address == null ? "localhost" : address.getHostName();
}
/**
* Gets local address.
*
* @return the local address
*/
public static InetAddress getLocalAddress() {
if (LOCAL_ADDRESS != null) {
return LOCAL_ADDRESS;
}
InetAddress localAddress = getLocalAddress0();
LOCAL_ADDRESS = localAddress;
return localAddress;
}
private static InetAddress getLocalAddress0() {
InetAddress localAddress = null;
try {
localAddress = InetAddress.getLocalHost();
if (isValidAddress(localAddress)) {
return localAddress;
}
} catch (Throwable e) {
LOGGER.warn("Failed to retrieving ip address, {}", e.getMessage(), e);
}
try {
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
if (interfaces != null) {
while (interfaces.hasMoreElements()) {
try {
NetworkInterface network = interfaces.nextElement();
Enumeration<InetAddress> addresses = network.getInetAddresses();
while (addresses.hasMoreElements()) {
try {
InetAddress address = addresses.nextElement();
if (isValidAddress(address)) {
return address;
}
} catch (Throwable e) {
LOGGER.warn("Failed to retrieving ip address, {}", e.getMessage(), e);
}
}
} catch (Throwable e) {
LOGGER.warn("Failed to retrieving ip address, {}", e.getMessage(), e);
}
}
}
} catch (Throwable e) {
LOGGER.warn("Failed to retrieving ip address, {}", e.getMessage(), e);
}
LOGGER.error("Could not get local host ip address, will use 127.0.0.1 instead.");
return localAddress;
}
/**
* Valid address.
*
* @param address the address
*/
public static void validAddress(InetSocketAddress address) {
if (address.getHostName() == null || 0 == address.getPort()) {
throw new IllegalArgumentException("invalid address:" + address);
}
}
/**
* is valid address
*
* @param address
* @return true if the given address is valid
*/
private static boolean isValidAddress(InetAddress address) {
if (address == null || address.isLoopbackAddress()) {
return false;
}
return isValidIp(address.getHostAddress(), false);
}
/**
* is valid IP
*
* @param ip
* @param validLocalAndAny Are 127.0.0.1 and 0.0.0.0 valid IPs?
* @return true if the given IP is valid
*/
public static boolean isValidIp(String ip, boolean validLocalAndAny) {
if (ip == null) {
return false;
}
ip = convertIpIfNecessary(ip);
if (validLocalAndAny) {
return IP_PATTERN.matcher(ip).matches();
} else {
return !ANY_HOST.equals(ip) && !LOCALHOST.equals(ip) && IP_PATTERN.matcher(ip).matches();
}
}
/**
* convert ip if necessary
*
* @param ip
* @return java.lang.String
*/
private static String convertIpIfNecessary(String ip) {
if (IP_PATTERN.matcher(ip).matches()) {
return ip;
} else {
try {
return InetAddress.getByName(ip).getHostAddress();
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
}
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
/**
* Number utility
*
* @author helloworlde
*/
public class NumberUtils {
/**
* <p>Convert a <code>String</code> to an <code>int</code>, returning a
* default value if the conversion fails.</p>
*
* <p>If the string is <code>null</code>, the default value is returned.</p>
*
* @param str the string to convert, may be null
* @param defaultValue the default value
* @return the int represented by the string, or the default if conversion fails
*/
public static int toInt(final String str, final int defaultValue) {
if (str == null) {
return defaultValue;
}
try {
return Integer.parseInt(str);
} catch (NumberFormatException nfe) {
return defaultValue;
}
}
public static Long toLong(String str, final Long defaultValue) {
if (str == null) {
return defaultValue;
}
try {
return Long.valueOf(str);
} catch (NumberFormatException nfe) {
return defaultValue;
}
}
public static Long toLong(String str) {
if (StringUtils.isNotBlank(str)) {
return Long.valueOf(str);
}
return null;
}
}

View File

@@ -0,0 +1,211 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* Reflection tools
*
* @author zhangsen
*/
public class ReflectionUtil {
/**
* The constant MAX_NEST_DEPTH.
*/
public static final int MAX_NEST_DEPTH = 20;
/**
* Gets class by name.
*
* @param className the class name
* @return the class by name
* @throws ClassNotFoundException the class not found exception
*/
public static Class<?> getClassByName(String className) throws ClassNotFoundException {
return Class.forName(className, true, Thread.currentThread().getContextClassLoader());
}
/**
* get Field Value
*
* @param target the target
* @param fieldName the field name
* @return field value
* @throws NoSuchFieldException the no such field exception
* @throws SecurityException the security exception
* @throws IllegalArgumentException the illegal argument exception
* @throws IllegalAccessException the illegal access exception
*/
public static Object getFieldValue(Object target, String fieldName)
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Class<?> cl = target.getClass();
int i = 0;
while ((i++) < MAX_NEST_DEPTH && cl != null) {
try {
Field field = cl.getDeclaredField(fieldName);
field.setAccessible(true);
return field.get(target);
} catch (Exception e) {
cl = cl.getSuperclass();
}
}
throw new NoSuchFieldException("class:" + target.getClass() + ", field:" + fieldName);
}
/**
* invoke Method
*
* @param target the target
* @param methodName the method name
* @return object
* @throws NoSuchMethodException the no such method exception
* @throws SecurityException the security exception
* @throws IllegalAccessException the illegal access exception
* @throws IllegalArgumentException the illegal argument exception
* @throws InvocationTargetException the invocation target exception
*/
public static Object invokeMethod(Object target, String methodName)
throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException {
Class<?> cl = target.getClass();
int i = 0;
while ((i++) < MAX_NEST_DEPTH && cl != null) {
try {
Method m = cl.getDeclaredMethod(methodName);
m.setAccessible(true);
return m.invoke(target);
} catch (Exception e) {
cl = cl.getSuperclass();
}
}
throw new NoSuchMethodException("class:" + target.getClass() + ", methodName:" + methodName);
}
/**
* invoke Method
*
* @param target the target
* @param methodName the method name
* @param parameterTypes the parameter types
* @param args the args
* @return object
* @throws NoSuchMethodException the no such method exception
* @throws SecurityException the security exception
* @throws IllegalAccessException the illegal access exception
* @throws IllegalArgumentException the illegal argument exception
* @throws InvocationTargetException the invocation target exception
*/
public static Object invokeMethod(Object target, String methodName, Class<?>[] parameterTypes, Object[] args)
throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException {
Class<?> cl = target.getClass();
int i = 0;
while ((i++) < MAX_NEST_DEPTH && cl != null) {
try {
Method m = cl.getDeclaredMethod(methodName, parameterTypes);
m.setAccessible(true);
return m.invoke(target, args);
} catch (Exception e) {
cl = cl.getSuperclass();
}
}
throw new NoSuchMethodException("class:" + target.getClass() + ", methodName:" + methodName);
}
/**
* invoke static Method
*
* @param targetClass the target class
* @param methodName the method name
* @param parameterTypes the parameter types
* @param parameterValues the parameter values
* @return object
* @throws NoSuchMethodException the no such method exception
* @throws SecurityException the security exception
* @throws IllegalAccessException the illegal access exception
* @throws IllegalArgumentException the illegal argument exception
* @throws InvocationTargetException the invocation target exception
*/
public static Object invokeStaticMethod(Class<?> targetClass, String methodName, Class<?>[] parameterTypes,
Object[] parameterValues)
throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException {
int i = 0;
while ((i++) < MAX_NEST_DEPTH && targetClass != null) {
try {
Method m = targetClass.getMethod(methodName, parameterTypes);
return m.invoke(null, parameterValues);
} catch (Exception e) {
targetClass = targetClass.getSuperclass();
}
}
throw new NoSuchMethodException("class:" + targetClass + ", methodName:" + methodName);
}
/**
* get Method by name
*
* @param classType the class type
* @param methodName the method name
* @param parameterTypes the parameter types
* @return method
* @throws NoSuchMethodException the no such method exception
* @throws SecurityException the security exception
*/
public static Method getMethod(Class<?> classType, String methodName, Class<?>[] parameterTypes)
throws NoSuchMethodException, SecurityException {
return classType.getMethod(methodName, parameterTypes);
}
/**
* get all interface of the clazz
*
* @param clazz the clazz
* @return set
*/
public static Set<Class<?>> getInterfaces(Class<?> clazz) {
if (clazz.isInterface()) {
return Collections.singleton(clazz);
}
Set<Class<?>> interfaces = new LinkedHashSet<>();
while (clazz != null) {
Class<?>[] ifcs = clazz.getInterfaces();
for (Class<?> ifc : ifcs) {
interfaces.addAll(getInterfaces(ifc));
}
clazz = clazz.getSuperclass();
}
return interfaces;
}
public static void modifyStaticFinalField(Class cla, String modifyFieldName, Object newValue)
throws NoSuchFieldException, IllegalAccessException {
Field field = cla.getDeclaredField(modifyFieldName);
field.setAccessible(true);
Field modifiers = field.getClass().getDeclaredField("modifiers");
modifiers.setAccessible(true);
modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(cla, newValue);
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
/**
* @author chd
*/
public class SizeUtil {
private static final long RADIX = 1024;
/**
* case size to byte length
* example:
* 2k => 2 * 1024
* 2m => 2 * 1024 * 1024
* 2g => 2 * 1024 * 1024 * 1024
* 2t => 2 * 1024 * 1024 * 1024 * 1024
* @param size the string size with unit
* @return the byte length
*/
public static long size2Long(String size) {
if (null == size || size.length() <= 1) {
throw new IllegalArgumentException("could not convert '" + size + "' to byte length");
}
String size2Lower = size.toLowerCase();
char unit = size2Lower.charAt(size.length() - 1);
long number;
try {
number = NumberUtils.toLong(size2Lower.substring(0, size.length() - 1));
} catch (NumberFormatException | NullPointerException ex) {
throw new IllegalArgumentException("could not convert '" + size + "' to byte length");
}
switch (unit) {
case 'k':
return number * RADIX;
case 'm':
return number * RADIX * RADIX;
case 'g':
return number * RADIX * RADIX * RADIX;
case 't':
return number * RADIX * RADIX * RADIX * RADIX;
default:
throw new IllegalArgumentException("could not convert '" + size + "' to byte length");
}
}
}

View File

@@ -0,0 +1,107 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
/**
* @author xingfudeshi@gmail.com
*/
public class StringFormatUtils {
private static final char MINUS = '-';
private static final char UNDERLINE = '_';
public static final char DOT = '.';
/**
* camelTo underline format
*
* @param param
* @return formatted string
*/
public static String camelToUnderline(String param) {
if (param == null || "".equals(param.trim())) {
return "";
}
int len = param.length();
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) {
char c = param.charAt(i);
if (Character.isUpperCase(c)) {
sb.append(UNDERLINE);
sb.append(Character.toLowerCase(c));
} else {
sb.append(c);
}
}
return sb.toString();
}
/**
* underline to camel
*
* @param param
* @return formatted string
*/
public static String underlineToCamel(String param) {
return formatCamel(param, UNDERLINE);
}
/**
* minus to camel
*
* @param param
* @return formatted string
*/
public static String minusToCamel(String param) {
return formatCamel(param, MINUS);
}
/**
* dot to camel
*
* @param param
* @return formatted string
*/
public static String dotToCamel(String param) {
return formatCamel(param, DOT);
}
/**
* format camel
*
* @param param
* @param sign
* @return formatted string
*/
private static String formatCamel(String param, char sign) {
if (param == null || "".equals(param.trim())) {
return "";
}
int len = param.length();
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) {
char c = param.charAt(i);
if (c == sign) {
if (++i < len) {
sb.append(Character.toUpperCase(param.charAt(i)));
}
} else {
sb.append(c);
}
}
return sb.toString();
}
}

View File

@@ -0,0 +1,265 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
import io.seata.common.Constants;
import io.seata.common.exception.ShouldNeverHappenException;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
/**
* The type String utils.
*
* @author slievrly
* @author Geng Zhang
*/
public class StringUtils {
private StringUtils() {
}
/**
* empty string
*/
public static final String EMPTY = "";
/**
* Is empty boolean.
*
* @param str the str
* @return the boolean
*/
public static boolean isNullOrEmpty(String str) {
return (str == null) || (str.isEmpty());
}
/**
* Is blank string ?
*
* @param str the str
* @return boolean boolean
*/
public static boolean isBlank(String str) {
int length;
if ((str == null) || ((length = str.length()) == 0)) {
return true;
}
for (int i = 0; i < length; i++) {
if (!Character.isWhitespace(str.charAt(i))) {
return false;
}
}
return true;
}
/**
* Is Not blank string ?
*
* @param str the str
* @return boolean boolean
*/
public static boolean isNotBlank(String str) {
return !isBlank(str);
}
/**
* Equals boolean.
*
* @param a the a
* @param b the b
* @return boolean
*/
public static boolean equals(String a, String b) {
if (a == null) {
return b == null;
}
return a.equals(b);
}
/**
* Equals ignore case boolean.
*
* @param a the a
* @param b the b
* @return the boolean
*/
public static boolean equalsIgnoreCase(String a, String b) {
if (a == null) {
return b == null;
}
return a.equalsIgnoreCase(b);
}
/**
* Input stream 2 string string.
*
* @param is the is
* @return the string
*/
public static String inputStream2String(InputStream is) {
if (is == null) {
return null;
}
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int i;
while ((i = is.read()) != -1) {
baos.write(i);
}
return baos.toString(Constants.DEFAULT_CHARSET_NAME);
} catch (Exception e) {
throw new ShouldNeverHappenException(e);
}
}
/**
* Input stream to byte array
*
* @param is the is
* @return the byte array
*/
public static byte[] inputStream2Bytes(InputStream is) {
if (is == null) {
return null;
}
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int i;
while ((i = is.read()) != -1) {
baos.write(i);
}
return baos.toByteArray();
} catch (Exception e) {
throw new ShouldNeverHappenException(e);
}
}
/**
* Object.toString()
*
* @param obj the obj
* @return string string
*/
public static String toString(Object obj) {
if (obj == null) {
return "null";
}
if (obj.getClass().isPrimitive()) {
return String.valueOf(obj);
}
if (obj instanceof String) {
return (String)obj;
}
if (obj instanceof Number || obj instanceof Character || obj instanceof Boolean) {
return String.valueOf(obj);
}
if (obj instanceof Date) {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S").format(obj);
}
if (obj instanceof Collection) {
StringBuilder sb = new StringBuilder();
sb.append("[");
if (!((Collection)obj).isEmpty()) {
for (Object o : (Collection)obj) {
sb.append(toString(o)).append(",");
}
sb.deleteCharAt(sb.length() - 1);
}
sb.append("]");
return sb.toString();
}
if (obj instanceof Map) {
Map<Object, Object> map = (Map)obj;
StringBuilder sb = new StringBuilder();
sb.append("{");
if (!map.isEmpty()) {
map.forEach((key, value) -> {
sb.append(toString(key)).append("->")
.append(toString(value)).append(",");
});
sb.deleteCharAt(sb.length() - 1);
}
sb.append("}");
return sb.toString();
}
StringBuilder sb = new StringBuilder();
Field[] fields = obj.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
sb.append(field.getName());
sb.append("=");
try {
Object f = field.get(obj);
if (f.getClass() == obj.getClass()) {
sb.append(f.toString());
} else {
sb.append(toString(f));
}
} catch (Exception e) {
}
sb.append(";");
}
return sb.toString();
}
/**
* Trim string to null if empty("").
*
* @param str the String to be trimmed, may be null
* @return the trimmed String
*/
public static String trimToNull(final String str) {
final String ts = trim(str);
return isEmpty(ts) ? null : ts;
}
/**
* Trim string, or null if string is null.
*
* @param str the String to be trimmed, may be null
* @return the trimmed string, {@code null} if null String input
*/
public static String trim(final String str) {
return str == null ? null : str.trim();
}
/**
* Checks if a CharSequence is empty ("") or null.
*
* @param cs the CharSequence to check, may be null
* @return {@code true} if the CharSequence is empty or null
*/
public static boolean isEmpty(final CharSequence cs) {
return cs == null || cs.length() == 0;
}
/**
* Checks if a CharSequence is not empty ("") and not null.
*
* @param cs the CharSequence to check, may be null
* @return {@code true} if the CharSequence is not empty and not null
*/
public static boolean isNotEmpty(final CharSequence cs) {
return !isEmpty(cs);
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common;
import java.util.Date;
/**
* The branch do for test
* @author wangzhongxiang
*/
public class BranchDO {
private String xid;
private Long transactionId;
private Integer status;
private Double test;
private Date gmtCreate;
public String getXid() {
return xid;
}
public Long getTransactionId() {
return transactionId;
}
public Integer getStatus() {
return status;
}
public Double getTest() {
return test;
}
public Date getGmtCreate() {
return gmtCreate;
}
public BranchDO() {
}
public BranchDO(String xid, Long transactionId, Integer status, Double test,
Date gmtCreate) {
this.xid = xid;
this.transactionId = transactionId;
this.status = status;
this.test = test;
this.gmtCreate = gmtCreate;
}
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common;
import java.util.Random;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* The type Xid test.
*
* @author Otis.z
*/
public class XIDTest {
/**
* Test set ip address.
*/
@Test
public void testSetIpAddress() {
XID.setIpAddress("127.0.0.1");
assertThat(XID.getIpAddress()).isEqualTo("127.0.0.1");
}
/**
* Test set port.
*/
@Test
public void testSetPort() {
XID.setPort(8080);
assertThat(XID.getPort()).isEqualTo(8080);
}
/**
* Test generate xid.
*/
@Test
public void testGenerateXID() {
long tranId = new Random().nextLong();
XID.setPort(8080);
XID.setIpAddress("127.0.0.1");
assertThat(XID.generateXID(tranId)).isEqualTo(XID.getIpAddress() + ":" + XID.getPort() + ":" + tranId);
}
/**
* Test get transaction id.
*/
@Test
public void testGetTransactionId() {
assertThat(XID.getTransactionId(null)).isEqualTo(-1);
assertThat(XID.getTransactionId("127.0.0.1:8080:8577662204289747564")).isEqualTo(8577662204289747564L);
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.exception;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* The dataAccess exception.
*
* @author lzf971107
*/
public class DataAccessExceptionTest {
@Test
public void testConstructorWithNoParameters() {
exceptionAsserts(new DataAccessException());
}
@Test
public void testConstructorWithFrameworkErrorCode() {
exceptionAsserts(new DataAccessException(FrameworkErrorCode.UnknownAppError));
}
@Test
public void testConstructorWithMessage() {
exceptionAsserts(new DataAccessException(FrameworkErrorCode.UnknownAppError.getErrMessage()));
}
@Test
public void testConstructorWithMessageAndFrameworkErrorCode() {
exceptionAsserts(new DataAccessException(FrameworkErrorCode.UnknownAppError.getErrMessage(), FrameworkErrorCode.UnknownAppError));
}
@Test
public void testConstructorWithCauseExceptionMessageAndFrameworkErrorCode() {
exceptionAsserts(new DataAccessException(new Throwable(), FrameworkErrorCode.UnknownAppError.getErrMessage(), FrameworkErrorCode.UnknownAppError));
}
@Test
public void testConstructorWithThrowable() {
exceptionAsserts(new DataAccessException(new Throwable(FrameworkErrorCode.UnknownAppError.getErrMessage())));
}
private static void exceptionAsserts(DataAccessException exception) {
assertThat(exception).isInstanceOf(DataAccessException.class).hasMessage(FrameworkErrorCode.UnknownAppError.getErrMessage());
assertThat(exception.getErrcode()).isEqualTo(FrameworkErrorCode.UnknownAppError);
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.exception;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* The eurekaRegistry exception.
*
* @author lzf971107
*/
public class EurekaRegistryExceptionTest {
@Test
public void testConstructorWithNoParameters() {
assertThat(new EurekaRegistryException()).isInstanceOf(EurekaRegistryException.class);
}
@Test
public void testConstructorWithMessage() {
exceptionAsserts(new EurekaRegistryException(FrameworkErrorCode.UnknownAppError.getErrMessage()));
}
@Test
public void testConstructorWithMessageAndThrowable() {
exceptionAsserts(new EurekaRegistryException(FrameworkErrorCode.UnknownAppError.getErrMessage(), new Throwable()));
}
@Test
public void testConstructorWithThrowable() {
assertThat(new EurekaRegistryException(new Throwable(FrameworkErrorCode.UnknownAppError.getErrMessage()))).isInstanceOf(EurekaRegistryException.class).hasMessage("java.lang.Throwable: " + FrameworkErrorCode.UnknownAppError.getErrMessage());
}
private static void exceptionAsserts(EurekaRegistryException exception) {
assertThat(exception).isInstanceOf(EurekaRegistryException.class).hasMessage(FrameworkErrorCode.UnknownAppError.getErrMessage());
}
}

View File

@@ -0,0 +1,153 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.exception;
import java.sql.SQLException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* The type Framework exception test.
*
* @author Otis.z
*/
public class FrameworkExceptionTest {
private Message message = new Message();
/**
* Test get errcode.
*/
@Test
public void testGetErrcode() {
Throwable throwable = Assertions.assertThrows(FrameworkException.class, () -> {
message.print4();
});
assertThat(throwable).hasMessage(FrameworkErrorCode.UnknownAppError.getErrMessage());
assertThat(((FrameworkException)throwable).getErrcode()).isEqualTo(FrameworkErrorCode.UnknownAppError);
}
/**
* Test nested exception.
*/
@Test
public void testNestedException() {
Throwable throwable = Assertions.assertThrows(FrameworkException.class, () -> {
message.print();
});
assertThat(throwable).hasMessage("");
}
/**
* Test nested exception 1.
*/
@Test
public void testNestedException1() {
Throwable throwable = Assertions.assertThrows(FrameworkException.class, () -> {
message.print1();
});
assertThat(throwable).hasMessage("nestedException");
}
/**
* Test nested exception 2.
*/
@Test
public void testNestedException2() {
Throwable throwable = Assertions.assertThrows(SQLException.class, () -> {
message.print2();
});
assertThat(throwable).hasMessageContaining("Message");
}
/**
* Test nested exception 3.
*/
@Test
public void testNestedException3() {
Throwable throwable = Assertions.assertThrows(SQLException.class, () -> {
message.print3();
});
assertThat(throwable).hasMessageContaining("Message");
}
/**
* Test nested exception 5.
*/
@Test
public void testNestedException5() {
Throwable throwable = Assertions.assertThrows(FrameworkException.class, () -> {
message.print5();
});
assertThat(throwable).hasMessage(FrameworkErrorCode.ExceptionCaught.getErrMessage());
}
/**
* Test nested exception 6.
*/
@Test
public void testNestedException6() {
Throwable throwable = Assertions.assertThrows(FrameworkException.class, () -> {
message.print6();
});
assertThat(throwable).hasMessage("frameworkException");
}
/**
* Test nested exception 7.
*/
@Test
public void testNestedException7() {
Throwable throwable = Assertions.assertThrows(FrameworkException.class, () -> {
message.print7();
});
assertThat(throwable).hasMessage("frameworkException");
}
/**
* Test nested exception 8.
*/
@Test
public void testNestedException8() {
Throwable throwable = Assertions.assertThrows(FrameworkException.class, () -> {
message.print8();
});
assertThat(throwable).hasMessage("throw");
}
/**
* Test nested exception 9.
*/
@Test
public void testNestedException9() {
Throwable throwable = Assertions.assertThrows(FrameworkException.class, () -> {
message.print9();
});
assertThat(throwable).hasMessage("frameworkExceptionMsg");
}
private static void exceptionAsserts(FrameworkException exception, String expectMessage) {
if (expectMessage == null) {
expectMessage = FrameworkErrorCode.UnknownAppError.getErrMessage();
}
assertThat(exception).isInstanceOf(FrameworkException.class).hasMessage(expectMessage);
assertThat(exception.getErrcode()).isEqualTo(FrameworkErrorCode.UnknownAppError);
}
}

View File

@@ -0,0 +1,103 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.exception;
import java.sql.SQLException;
/**
* The type Message.
*
* @author Otis.z
* @since 2019 /3/1
*/
public class Message {
/**
* Print.
*/
public void print() {
throw FrameworkException.nestedException(new Throwable(Message.class.getSimpleName()));
}
/**
* Print 1.
*/
public void print1() {
throw FrameworkException.nestedException("nestedException", new Throwable(Message.class.getSimpleName()));
}
/**
* Print 2.
*
* @throws SQLException the sql exception
*/
public void print2() throws SQLException {
throw FrameworkException.nestedSQLException("nestedException", new Throwable(Message.class.getSimpleName()));
}
/**
* Print 3.
*
* @throws SQLException the sql exception
*/
public void print3() throws SQLException {
throw FrameworkException.nestedSQLException(new Throwable(Message.class.getSimpleName()));
}
/**
* Print 4.
*/
public void print4() {
throw new FrameworkException();
}
/**
* Print 5.
*/
public void print5() {
throw new FrameworkException(FrameworkErrorCode.ExceptionCaught);
}
/**
* Print 6.
*/
public void print6() {
throw new FrameworkException("frameworkException", FrameworkErrorCode.InitSeataClientError);
}
/**
* Print 7.
*/
public void print7() {
throw new FrameworkException(new Throwable("throw"), "frameworkException",
FrameworkErrorCode.ChannelIsNotWritable);
}
/**
* Print 8.
*/
public void print8() {
throw new FrameworkException(new Throwable("throw"));
}
/**
* Print 9.
*/
public void print9() {
throw new FrameworkException(new Throwable(), "frameworkExceptionMsg");
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.exception;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* The notSupportYet exception.
*
* @author lzf971107
*/
public class NotSupportYetExceptionTest {
@Test
public void testConstructorWithNoParameters() {
assertThat(new NotSupportYetException()).isInstanceOf(NotSupportYetException.class);
}
@Test
public void testConstructorWithMessage() {
exceptionAsserts(new NotSupportYetException(FrameworkErrorCode.UnknownAppError.getErrMessage()));
}
@Test
public void testConstructorWithMessageAndThrowable() {
exceptionAsserts(new NotSupportYetException(FrameworkErrorCode.UnknownAppError.getErrMessage(), new Throwable()));
}
@Test
public void testConstructorWithThrowable() {
assertThat(new NotSupportYetException(new Throwable(FrameworkErrorCode.UnknownAppError.getErrMessage()))).isInstanceOf(NotSupportYetException.class).hasMessage("java.lang.Throwable: " + FrameworkErrorCode.UnknownAppError.getErrMessage());
}
private static void exceptionAsserts(NotSupportYetException exception) {
assertThat(exception).isInstanceOf(NotSupportYetException.class).hasMessage(FrameworkErrorCode.UnknownAppError.getErrMessage());
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.exception;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* The shouldNeverHappen exception.
*
* @author lzf971107
*/
public class ShouldNeverHappenExceptionTest {
@Test
public void testConstructorWithNoParameters() {
assertThat(new ShouldNeverHappenException()).isInstanceOf(ShouldNeverHappenException.class);
}
@Test
public void testConstructorWithMessage() {
exceptionAsserts(new ShouldNeverHappenException(FrameworkErrorCode.UnknownAppError.getErrMessage()));
}
@Test
public void testConstructorWithMessageAndThrowable() {
exceptionAsserts(new ShouldNeverHappenException(FrameworkErrorCode.UnknownAppError.getErrMessage(), new Throwable()));
}
@Test
public void testConstructorWithThrowable() {
assertThat(new ShouldNeverHappenException(new Throwable(FrameworkErrorCode.UnknownAppError.getErrMessage()))).isInstanceOf(ShouldNeverHappenException.class).hasMessage("java.lang.Throwable: " + FrameworkErrorCode.UnknownAppError.getErrMessage());
}
private static void exceptionAsserts(ShouldNeverHappenException exception) {
assertThat(exception).isInstanceOf(ShouldNeverHappenException.class).hasMessage(FrameworkErrorCode.UnknownAppError.getErrMessage());
}
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.exception;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class StoreExceptionTest {
@Test
public void testConstructorWithNoParameters() {
exceptionAsserts(new StoreException());
}
@Test
public void testConstructorWithFrameworkErrorCode() {
exceptionAsserts(new StoreException(FrameworkErrorCode.UnknownAppError));
}
@Test
public void testConstructorWithMessage() {
exceptionAsserts(new StoreException(FrameworkErrorCode.UnknownAppError.getErrMessage()));
}
@Test
public void testConstructorWithMessageAndFrameworkErrorCode() {
exceptionAsserts(
new StoreException(FrameworkErrorCode.UnknownAppError.getErrMessage(), FrameworkErrorCode.UnknownAppError));
}
@Test
public void testConstructorWithCauseExceptionMessageAndFrameworkErrorCode() {
exceptionAsserts(new StoreException(new Throwable(), FrameworkErrorCode.UnknownAppError.getErrMessage(),
FrameworkErrorCode.UnknownAppError));
}
@Test
public void testConstructorWithThrowable() {
exceptionAsserts(new StoreException(new Throwable(FrameworkErrorCode.UnknownAppError.getErrMessage())));
}
@Test
public void testConstructorWithThrowableAndMessage() {
exceptionAsserts(new StoreException(new Throwable(), FrameworkErrorCode.UnknownAppError.getErrMessage()));
}
private static void exceptionAsserts(StoreException exception) {
assertThat(exception).isInstanceOf(StoreException.class).hasMessage(
FrameworkErrorCode.UnknownAppError.getErrMessage());
assertThat(exception.getErrcode()).isEqualTo(FrameworkErrorCode.UnknownAppError);
}
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.loader;
/**
* The type Chinese hello.
*
* @author Otis.z
*/
@LoadLevel(name = "ChineseHello", order = Integer.MIN_VALUE)
public class ChineseHello implements Hello {
@Override
public String say() {
return "ni hao!";
}
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.loader;
/**
* The type English hello.
*
* @author Otis.z
*/
@LoadLevel(name = "EnglishHello", order = 1)
public class EnglishHello implements Hello {
@Override
public String say() {
return "hello!";
}
}

View File

@@ -0,0 +1,129 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.loader;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* The type Enhanced service loader test.
*
* @author Otis.z
*/
public class EnhancedServiceLoaderTest {
/**
* Test load by class and class loader.
*/
@Test
public void testLoadByClassAndClassLoader() {
Hello load = EnhancedServiceLoader.load(Hello.class, Hello.class.getClassLoader());
Assertions.assertEquals(load.say(), "Olá.");
}
/**
* Test load exception.
*/
@Test
public void testLoadException() {
Assertions.assertThrows(EnhancedServiceNotFoundException.class, () -> {
EnhancedServiceLoaderTest load = EnhancedServiceLoader.load(EnhancedServiceLoaderTest.class);
});
}
/**
* Test load by class.
*/
@Test
public void testLoadByClass() {
Hello load = EnhancedServiceLoader.load(Hello.class);
assertThat(load.say()).isEqualTo("Olá.");
}
/**
* Test load by class and activate name.
*/
@Test
public void testLoadByClassAndActivateName() {
Hello englishHello = EnhancedServiceLoader.load(Hello.class, "EnglishHello");
assertThat(englishHello.say()).isEqualTo("hello!");
}
/**
* Test load by class and class loader and activate name.
*/
@Test
public void testLoadByClassAndClassLoaderAndActivateName() {
Hello englishHello = EnhancedServiceLoader
.load(Hello.class, "EnglishHello", EnhancedServiceLoaderTest.class.getClassLoader());
assertThat(englishHello.say()).isEqualTo("hello!");
}
/**
* Gets all extension class.
*/
@Test
public void getAllExtensionClass() {
List<Class> allExtensionClass = EnhancedServiceLoader.getAllExtensionClass(Hello.class);
assertThat(allExtensionClass.get(3).getSimpleName()).isEqualTo((LatinHello.class.getSimpleName()));
assertThat(allExtensionClass.get(2).getSimpleName()).isEqualTo((FrenchHello.class.getSimpleName()));
assertThat(allExtensionClass.get(1).getSimpleName()).isEqualTo((EnglishHello.class.getSimpleName()));
assertThat(allExtensionClass.get(0).getSimpleName()).isEqualTo((ChineseHello.class.getSimpleName()));
}
/**
* Gets all extension class 1.
*/
@Test
public void getAllExtensionClass1() {
List<Class> allExtensionClass = EnhancedServiceLoader
.getAllExtensionClass(Hello.class, ClassLoader.getSystemClassLoader());
assertThat(allExtensionClass).isNotEmpty();
}
@Test
public void getSingletonExtensionInstance(){
Hello hello1 = EnhancedServiceLoader.load(Hello.class, "ChineseHello");
Hello hello2 = EnhancedServiceLoader.load(Hello.class, "ChineseHello");
assertThat(hello1 == hello2).isTrue();
}
@Test
public void getMultipleExtensionInstance(){
Hello hello1 = EnhancedServiceLoader.load(Hello.class, "LatinHello");
Hello hello2 = EnhancedServiceLoader.load(Hello.class, "LatinHello");
assertThat(hello1 == hello2).isFalse();
}
@Test
public void getAllInstances(){
List<Hello> hellows1 = EnhancedServiceLoader.loadAll(Hello.class);
List<Hello> hellows2 = EnhancedServiceLoader.loadAll(Hello.class);
for (Hello hello : hellows1){
if (!hello.say().equals("Olá.")) {
assertThat(hellows2.contains(hello)).isTrue();
}
else{
assertThat(hellows2.contains(hello)).isFalse();
}
}
}
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.loader;
/**
* The type French hello.
*
* @author Otis.z
*/
@LoadLevel(name = "FrenchHello", order = 2)
public class FrenchHello implements Hello {
@Override
public String say() {
return "Bonjour";
}
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.loader;
/**
* The interface Hello.
*
* @author Otis.z
*/
public interface Hello {
/**
* Say string.
*
* @return the string
*/
String say();
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.loader;
/**
* The type LatinHello
*
* @author haozhibei
*/
@LoadLevel(name = "LatinHello",order = 3, scope = Scope.PROTOTYPE)
public class LatinHello implements Hello {
@Override
public String say() {
return "Olá.";
}
}

View File

@@ -0,0 +1,58 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.rpc;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
/**
* The state statistics test.
*
* @author ph3636
*/
public class RpcStatusTest {
public static final String SERVICE = "127.0.0.1:80";
@Test
public void getStatus() {
RpcStatus rpcStatus1 = RpcStatus.getStatus(SERVICE);
Assertions.assertNotNull(rpcStatus1);
RpcStatus rpcStatus2 = RpcStatus.getStatus(SERVICE);
Assertions.assertEquals(rpcStatus1, rpcStatus2);
}
@Test
public void removeStatus() {
RpcStatus old = RpcStatus.getStatus(SERVICE);
RpcStatus.removeStatus(SERVICE);
Assertions.assertNotEquals(RpcStatus.getStatus(SERVICE), old);
}
@Test
public void beginCount() {
RpcStatus.beginCount(SERVICE);
Assertions.assertEquals(RpcStatus.getStatus(SERVICE).getActive(), 1);
}
@Test
public void endCount() {
RpcStatus.endCount(SERVICE);
Assertions.assertEquals(RpcStatus.getStatus(SERVICE).getActive(), 0);
Assertions.assertEquals(RpcStatus.getStatus(SERVICE).getTotal(), 1);
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.thread;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Test;
/**
* @author Otis.z
*/
public class NamedThreadFactoryTest {
private static final int THREAD_TOTAL_SIZE = 3;
private static final int DEFAULT_THREAD_PREFIX_COUNTER = 1;
@Test
public void testNewThread() {
NamedThreadFactory namedThreadFactory = new NamedThreadFactory("testNameThread", 5);
Thread testNameThread = namedThreadFactory
.newThread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
assertThat(testNameThread.getName()).startsWith("testNameThread");
assertThat(testNameThread.isDaemon()).isTrue();
}
@Test
public void testConstructorWithPrefixAndDaemons() {
NamedThreadFactory factory = new NamedThreadFactory("prefix", true);
Thread thread = factory.newThread(() -> {});
assertThat(thread.getName()).startsWith("prefix");
assertThat(thread.isDaemon()).isTrue();
}
@Test
public void testThreadNameHasCounterWithPrefixCounter() {
NamedThreadFactory factory = new NamedThreadFactory("prefix", THREAD_TOTAL_SIZE, true);
for (int i = 0; i < THREAD_TOTAL_SIZE; i ++) {
Thread thread = factory.newThread(() -> {});
// the first _DEFAULT_THREAD_PREFIX_COUNTER is meaning thread counter
assertThat("prefix_" + DEFAULT_THREAD_PREFIX_COUNTER + "_" + (i + 1) + "_" + THREAD_TOTAL_SIZE)
.isEqualTo(thread.getName());
}
}
@Test
public void testNamedThreadFactoryWithSecurityManager() {
NamedThreadFactory factory = new NamedThreadFactory("testThreadGroup", true);
Thread thread = factory.newThread(() -> {});
assertThat(thread.getThreadGroup()).isNotNull();
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.thread;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class PositiveAtomicCounterTest {
@Test
public void testConstructor() {
PositiveAtomicCounter counter = new PositiveAtomicCounter();
assertThat(counter).isInstanceOf(PositiveAtomicCounter.class);
}
@Test
public void testIncrementAndGet() {
PositiveAtomicCounter counter = new PositiveAtomicCounter();
assertThat(counter.incrementAndGet()).isEqualTo(1);
}
@Test
public void testGetAndIncrement() {
PositiveAtomicCounter counter = new PositiveAtomicCounter();
assertThat(counter.getAndIncrement()).isEqualTo(0);
}
@Test
public void testGet() {
PositiveAtomicCounter counter = new PositiveAtomicCounter();
assertThat(counter.get()).isEqualTo(0);
}
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.thread;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Created by guoyao on 2019/2/26.
*/
public class RejectedPoliciesTest {
private final int DEFAULT_CORE_POOL_SIZE = 1;
private final int DEFAULT_KEEP_ALIVE_TIME = 10;
private final int MAX_QUEUE_SIZE = 1;
/**
* Test runs oldest task policy.
*
* @throws Exception the exception
*/
@Test
public void testRunsOldestTaskPolicy() throws Exception {
AtomicInteger atomicInteger = new AtomicInteger();
ThreadPoolExecutor poolExecutor =
new ThreadPoolExecutor(DEFAULT_CORE_POOL_SIZE, DEFAULT_CORE_POOL_SIZE, DEFAULT_KEEP_ALIVE_TIME,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(MAX_QUEUE_SIZE),
new NamedThreadFactory("OldestRunsPolicy", DEFAULT_CORE_POOL_SIZE),
RejectedPolicies.runsOldestTaskPolicy());
CountDownLatch downLatch1 = new CountDownLatch(1);
CountDownLatch downLatch2 = new CountDownLatch(1);
CountDownLatch downLatch3 = new CountDownLatch(1);
//task1
poolExecutor.execute(() -> {
try {
//wait the oldest task of queue count down
downLatch1.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
atomicInteger.getAndAdd(1);
});
assertThat(atomicInteger.get()).isEqualTo(0);
//task2
poolExecutor.execute(() -> {
// run second
atomicInteger.getAndAdd(2);
});
//task3
poolExecutor.execute(() -> {
downLatch2.countDown();
//task3 run
atomicInteger.getAndAdd(3);
downLatch3.countDown();
});
//only the task2 run which is the oldest task of queue
assertThat(atomicInteger.get()).isEqualTo(2);
downLatch1.countDown();
downLatch2.await();
//wait task3 run +3
downLatch3.await();
//run task3
assertThat(atomicInteger.get()).isEqualTo(6);
}
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
import io.seata.common.BranchDO;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
/**
* The bean utils test
*
* @author wangzhongxiang
*/
public class BeanUtilsTest {
@Test
public void testBeanToStringNotNull() {
BranchDO branchDO = new BranchDO("xid123123", 123L, 1, 2.2, new Date());
Assertions.assertNotNull(BeanUtils.beanToString(branchDO));
}
@Test
public void testBeanToStringNull() {
BranchDO branchDO = null;
Assertions.assertNull(BeanUtils.beanToString(branchDO));
}
@Test
public void testMapToObjectNotNull() {
Map<String, String> map = new HashMap<>();
Date date = new Date();
map.put("xid", "192.166.166.11:9010:12423424234234");
map.put("transactionId", "12423424234234");
map.put("status", "2");
map.put("test", "22.22");
map.put("gmtCreate", String.valueOf(date.getTime()));
BranchDO branchDO =
(BranchDO) BeanUtils.mapToObject(map, BranchDO.class);
Assertions.assertEquals(map.get("xid"), branchDO.getXid());
Assertions.assertEquals(Long.valueOf(map.get("transactionId")), branchDO.getTransactionId());
Assertions.assertEquals(Integer.valueOf(map.get("status")), branchDO.getStatus());
Assertions.assertEquals(Double.valueOf(map.get("test")), branchDO.getTest());
Assertions.assertEquals(new Date(date.getTime()), branchDO.getGmtCreate());
}
@Test
public void testMapToObjectNull() {
Map<String, String> map = null;
BranchDO branchDO =
(BranchDO) BeanUtils.mapToObject(map, BranchDO.class);
Assertions.assertNull(branchDO);
}
@Test
public void testObjectToMapNotNull() {
BranchDO branchDO = new BranchDO("xid123123", 123L, 1, 2.2, new Date());
Map<String, String> map = BeanUtils.objectToMap(branchDO);
Assertions.assertEquals(branchDO.getXid(), map.get("xid"));
Assertions.assertEquals(branchDO.getTransactionId(), Long.valueOf(map.get("transactionId")));
Assertions.assertEquals(branchDO.getStatus(), Integer.valueOf(map.get("status")));
Assertions.assertEquals(branchDO.getTest(), Double.valueOf(map.get("test")));
Assertions.assertEquals(branchDO.getGmtCreate().getTime(),Long.valueOf(map.get("gmtCreate")));
}
@Test
public void testObjectToMapNull() {
BranchDO branchDO = null;
Map<String, String> map = BeanUtils.objectToMap(branchDO);
Assertions.assertNull(map);
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
import java.io.UnsupportedEncodingException;
import java.sql.SQLException;
import javax.sql.rowset.serial.SerialBlob;
import io.seata.common.Constants;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertNull;
/**
* The type Blob utils test.
*
* @author Otis.z
* @author Geng Zhang
*/
public class BlobUtilsTest {
/**
* Test string 2 blob.
*
* @throws SQLException the sql exception
*/
@Test
public void testString2blob() throws SQLException {
assertNull(BlobUtils.string2blob(null));
assertThat(BlobUtils.string2blob("123abc")).isEqualTo(
new SerialBlob("123abc".getBytes(Constants.DEFAULT_CHARSET)));
}
/**
* Test blob 2 string.
*
* @throws SQLException the sql exception
*/
@Test
public void testBlob2string() throws SQLException {
assertNull(BlobUtils.blob2string(null));
assertThat(BlobUtils.blob2string(new SerialBlob("123absent".getBytes(Constants.DEFAULT_CHARSET)))).isEqualTo(
"123absent");
}
@Test
void bytes2Blob() throws UnsupportedEncodingException, SQLException {
assertNull(BlobUtils.bytes2Blob(null));
byte[] bs = "xxaaadd".getBytes(Constants.DEFAULT_CHARSET_NAME);
assertThat(BlobUtils.bytes2Blob(bs)).isEqualTo(
new SerialBlob(bs));
}
@Test
void blob2Bytes() throws UnsupportedEncodingException, SQLException {
assertNull(BlobUtils.blob2Bytes(null));
byte[] bs = "xxaaadd".getBytes(Constants.DEFAULT_CHARSET_NAME);
assertThat(BlobUtils.blob2Bytes(new SerialBlob(bs))).isEqualTo(
bs);
}
}

View File

@@ -0,0 +1,239 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
/**
* The type Collection utils test.
*
* @author Geng Zhang
*/
public class CollectionUtilsTest {
@Test
public void test_isEmpty_isNotEmpty() {
// case 1: null
List<String> list = null;
String[] array = null;
Map<Object, Object> map = null;
Assertions.assertTrue(CollectionUtils.isEmpty(list));
Assertions.assertTrue(CollectionUtils.isEmpty(array));
Assertions.assertTrue(CollectionUtils.isEmpty(map));
Assertions.assertFalse(CollectionUtils.isNotEmpty(list));
Assertions.assertFalse(CollectionUtils.isNotEmpty(array));
Assertions.assertFalse(CollectionUtils.isNotEmpty(map));
// case 2: empty
list = new ArrayList<>();
array = new String[0];
map = new HashMap<>();
Assertions.assertTrue(CollectionUtils.isEmpty(list));
Assertions.assertTrue(CollectionUtils.isEmpty(array));
Assertions.assertTrue(CollectionUtils.isEmpty(map));
Assertions.assertFalse(CollectionUtils.isNotEmpty(list));
Assertions.assertFalse(CollectionUtils.isNotEmpty(array));
Assertions.assertFalse(CollectionUtils.isNotEmpty(map));
// case 3: not empty
list.add("1");
array = new String[]{"1"};
map.put("test", "test");
Assertions.assertFalse(CollectionUtils.isEmpty(list));
Assertions.assertFalse(CollectionUtils.isEmpty(array));
Assertions.assertFalse(CollectionUtils.isEmpty(map));
Assertions.assertTrue(CollectionUtils.isNotEmpty(list));
Assertions.assertTrue(CollectionUtils.isNotEmpty(array));
Assertions.assertTrue(CollectionUtils.isNotEmpty(map));
}
/**
* Is size equals.
*/
@Test
public void isSizeEquals() {
List<String> list0 = new ArrayList<>();
List<String> list1 = new ArrayList<>();
Assertions.assertTrue(CollectionUtils.isSizeEquals(null, null));
Assertions.assertFalse(CollectionUtils.isSizeEquals(null, list0));
Assertions.assertFalse(CollectionUtils.isSizeEquals(list1, null));
Assertions.assertTrue(CollectionUtils.isSizeEquals(list0, list1));
list0.add("111");
Assertions.assertFalse(CollectionUtils.isSizeEquals(list0, list1));
list1.add("111");
Assertions.assertTrue(CollectionUtils.isSizeEquals(list0, list1));
}
/**
* Encode map.
*/
@Test
public void encodeMap() {
Map<String, String> map = null;
Assertions.assertNull(CollectionUtils.encodeMap(map));
map = new LinkedHashMap<>();
Assertions.assertEquals("", CollectionUtils.encodeMap(map));
map.put("x", "1");
Assertions.assertEquals("x=1", CollectionUtils.encodeMap(map));
map.put("y", "2");
Assertions.assertEquals("x=1&y=2", CollectionUtils.encodeMap(map));
}
/**
* Decode map.
*/
@Test
public void decodeMap() {
Assertions.assertNull(CollectionUtils.decodeMap(null));
Map<String, String> map = CollectionUtils.decodeMap("");
Assertions.assertEquals(0, map.size());
map = CollectionUtils.decodeMap("&");
Assertions.assertEquals(0, map.size());
map = CollectionUtils.decodeMap("=");
Assertions.assertEquals(0, map.size());
map = CollectionUtils.decodeMap("&=");
Assertions.assertEquals(0, map.size());
map = CollectionUtils.decodeMap("x=1");
Assertions.assertEquals(1, map.size());
Assertions.assertEquals("1", map.get("x"));
map = CollectionUtils.decodeMap("x=1&y=2");
Assertions.assertEquals(2, map.size());
Assertions.assertEquals("2", map.get("y"));
}
/**
* Test to upper list.
*/
@Test
public void testToUpperList() {
List<String> sourceList = null;
Assertions.assertNull(CollectionUtils.toUpperList(sourceList));
sourceList = new ArrayList<>();
Assertions.assertEquals(Collections.EMPTY_LIST, CollectionUtils.toUpperList(sourceList));
List<String> anotherList = new ArrayList<>();
sourceList.add("a");
anotherList.add("A");
sourceList.add("b");
anotherList.add("b");
sourceList.add("c");
anotherList.add("C");
Assertions.assertEquals(CollectionUtils.toUpperList(sourceList), CollectionUtils.toUpperList(anotherList));
anotherList.add("D");
Assertions.assertTrue(
CollectionUtils.toUpperList(anotherList).containsAll(CollectionUtils.toUpperList(sourceList)));
List<String> listWithNull = new ArrayList<>();
listWithNull.add("foo");
listWithNull.add(null);
listWithNull.add("bar");
List<String> listUpperWithNull = new ArrayList<>();
listUpperWithNull.add("FOO");
listUpperWithNull.add(null);
listUpperWithNull.add("BAR");
Assertions.assertEquals(listUpperWithNull, CollectionUtils.toUpperList(listWithNull));
}
@Test
public void testIsEmptyWithArrays() {
String[] emptyArray = {};
String[] filledArray = {"Foo", "Bar"};
Assertions.assertTrue(CollectionUtils.isEmpty(emptyArray));
Assertions.assertFalse(CollectionUtils.isEmpty(filledArray));
}
@Test
public void testIsEmptyWithCollection() {
List<String> emptyCollection = new ArrayList<>();
List<String> filledCollection = new ArrayList<>();
filledCollection.add("Foo");
filledCollection.add("Bar");
Assertions.assertTrue(CollectionUtils.isEmpty(emptyCollection));
Assertions.assertFalse(CollectionUtils.isEmpty(filledCollection));
}
@Test
public void testCollectionToString() {
List<String> emptyCollection = new ArrayList<>();
List<String> filledCollection = new ArrayList<>();
filledCollection.add("Foo");
filledCollection.add("Bar");
Assertions.assertEquals("", CollectionUtils.toString(emptyCollection));
Assertions.assertEquals("[Foo,Bar]", CollectionUtils.toString(filledCollection));
}
@Test
public void testIsEmpty() {
Map<String, Object> map = new HashMap<>();
Assertions.assertTrue(CollectionUtils.isEmpty(map));
map.put("k", "v");
Assertions.assertFalse(CollectionUtils.isEmpty(map));
map = null;
Assertions.assertTrue(CollectionUtils.isEmpty(map));
}
@Test
public void testObjectMapToStringMap() {
Map<String, Object> objMap = new HashMap<>();
Date now = new Date();
objMap.put("a", "aa");
objMap.put("b", 22);
objMap.put("c", now);
Map<String, String> strMap = CollectionUtils.toStringMap(objMap);
Assertions.assertEquals("aa", strMap.get("a"));
Assertions.assertEquals("22", strMap.get("b"));
Assertions.assertEquals(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S").format(now), strMap.get("c"));
}
@Test
public void test_getLast() {
// case 1: null
Assertions.assertNull(CollectionUtils.getLast(null));
// case 2: empty
List<String> emptyList = Collections.EMPTY_LIST;
Assertions.assertNull(CollectionUtils.getLast(emptyList));
// case 3: not empty
List<String> list = new ArrayList<>();
list.add("Foo");
list.add("Bar");
Assertions.assertEquals("Bar", CollectionUtils.getLast(list));
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
import java.io.IOException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class CompressUtilTest {
@Test
public void testCompress() throws IOException {
byte[] bytes = new byte[]{31, -117, 8, 0, 0, 0, 0, 0, 0, 0,
99, 100, 98, 6, 0, 29, -128, -68, 85, 3, 0, 0, 0};
Assertions.assertArrayEquals(bytes,
CompressUtil.compress(new byte[]{1, 2, 3}));
}
@Test
public void testUncompress() throws IOException {
byte[] bytes = new byte[]{31, -117, 8, 0, 0, 0, 0, 0, 0, 0,
99, 100, 98, 6, 0, 29, -128, -68, 85, 3, 0, 0, 0};
Assertions.assertArrayEquals(new byte[]{1, 2, 3},
CompressUtil.uncompress(bytes));
}
@Test
public void testIsCompressData() {
Assertions.assertFalse(CompressUtil.isCompressData(null));
Assertions.assertFalse(CompressUtil.isCompressData(new byte[0]));
Assertions.assertFalse(CompressUtil.isCompressData(new byte[]{31, 11}));
Assertions.assertFalse(
CompressUtil.isCompressData(new byte[]{31, 11, 0}));
Assertions.assertTrue(
CompressUtil.isCompressData(new byte[]{31, -117, 0}));
}
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
import java.security.KeyPair;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
/**
* @author funkye
*/
public class ConfigToolsTest {
@Test
public void test() throws Exception {
KeyPair keyPair = ConfigTools.getKeyPair();
String publicKeyStr = ConfigTools.getPublicKey(keyPair);
String privateKeyStr = ConfigTools.getPrivateKey(keyPair);
System.out.println("publicKeyStr:" + publicKeyStr);
System.out.println("privateKeyStr:" + privateKeyStr);
String password = "123456";
String byte2Base64 = ConfigTools.privateEncrypt(password, privateKeyStr);
System.out.println("byte2Base64" + byte2Base64);
String pw = ConfigTools.publicDecrypt(byte2Base64, publicKeyStr);
Assertions.assertEquals(pw, password);
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class DurationUtilTest {
@Test
public void testParse() {
Assertions.assertNull(DurationUtil.parse("d"));
Assertions.assertNull(DurationUtil.parse("h"));
Assertions.assertNull(DurationUtil.parse("m"));
Assertions.assertNull(DurationUtil.parse("s"));
Assertions.assertNull(DurationUtil.parse("ms"));
Assertions.assertEquals(-1L, DurationUtil.parse("").getSeconds());
Assertions.assertEquals(0L, DurationUtil.parse("8").getSeconds());
Assertions.assertEquals(0L, DurationUtil.parse("8ms").getSeconds());
Assertions.assertEquals(8L, DurationUtil.parse("8s").getSeconds());
Assertions.assertEquals(480L, DurationUtil.parse("8m").getSeconds());
Assertions.assertEquals(28800L, DurationUtil.parse("8h").getSeconds());
Assertions.assertEquals(691200L,
DurationUtil.parse("8d").getSeconds());
}
@Test
public void testParseThrowException() {
Assertions.assertThrows(UnsupportedOperationException.class,
() -> DurationUtil.parse("a"));
Assertions.assertThrows(UnsupportedOperationException.class,
() -> DurationUtil.parse("as"));
}
}

View File

@@ -0,0 +1,73 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
/**
* @author caioguedes
*/
public class IOUtilTest {
@Test
public void testCloseWithSingleParameter() {
FakeResource resource = new FakeResource();
IOUtil.close(resource);
Assertions.assertTrue(resource.isClose());
}
@Test
public void testCloseWithArrayParameter() {
FakeResource resource1 = new FakeResource();
FakeResource resource2 = new FakeResource();
IOUtil.close(resource1, resource2);
Assertions.assertTrue(resource1.isClose());
Assertions.assertTrue(resource2.isClose());
}
@Test
public void testIgnoreExceptionOnClose() {
FakeResource resource = new FakeResource() {
@Override
public void close() throws Exception {
super.close();
throw new Exception("Ops!");
}
};
IOUtil.close(resource);
Assertions.assertTrue(resource.isClose());
}
private class FakeResource implements AutoCloseable{
private boolean close = false;
@Override
public void close() throws Exception {
this.close = true;
}
public boolean isClose() {
return close;
}
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertEquals;
class IdWorkerTest {
@Test
void testNegativeWorkerId() {
assertThrows(IllegalArgumentException.class, () -> {
new IdWorker(-1L);
}, "should throw IllegalArgumentException when workerId is negative");
}
@Test
void testTooLargeWorkerId() {
assertThrows(IllegalArgumentException.class, () -> {
new IdWorker(1024L);
}, "should throw IllegalArgumentException when workerId is bigger than 1023");
}
@Test
void testNextId() {
IdWorker worker = new IdWorker(null);
long id1 = worker.nextId();
long id2 = worker.nextId();
assertEquals(1L, id2 - id1, "increment step should be 1");
}
}

View File

@@ -0,0 +1,184 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
/**
* The type Net util test.
*
* @author Otis.z
*/
public class NetUtilTest {
private InetSocketAddress ipv4 = new InetSocketAddress(Inet4Address.getLocalHost().getHostName(), 3902);
private InetSocketAddress ipv6 = new InetSocketAddress(Inet6Address.getLocalHost().getHostName(), 3904);
/**
* Instantiates a new Net util test.
*
* @throws UnknownHostException the unknown host exception
*/
public NetUtilTest() throws UnknownHostException {
}
/**
* Test to string address.
*/
@Test
public void testToStringAddress() {
try {
String stringAddress = NetUtil.toStringAddress(InetSocketAddress.createUnresolved("127.0.0.1", 9828));
} catch (Exception e) {
assertThat(e).isInstanceOf(NullPointerException.class);
}
}
/**
* Test to string address 1.
*/
@Test
public void testToStringAddress1() {
assertThat(NetUtil.toStringAddress((SocketAddress)ipv4))
.isEqualTo(ipv4.getAddress().getHostAddress() + ":" + ipv4.getPort());
assertThat(NetUtil.toStringAddress((SocketAddress)ipv6)).isEqualTo(
ipv6.getAddress().getHostAddress() + ":" + ipv6.getPort());
}
/**
* Test to string address 2.
*/
@Test
public void testToStringAddress2() {
assertThat(NetUtil.toStringAddress(ipv4)).isEqualTo(
ipv4.getAddress().getHostAddress() + ":" + ipv4.getPort());
assertThat(NetUtil.toStringAddress(ipv6)).isEqualTo(
ipv6.getAddress().getHostAddress() + ":" + ipv6.getPort());
}
/**
* Test to ip address.
*
* @throws UnknownHostException the unknown host exception
*/
@Test
public void testToIpAddress() throws UnknownHostException {
assertThat(NetUtil.toIpAddress(ipv4)).isEqualTo(ipv4.getAddress().getHostAddress());
assertThat(NetUtil.toIpAddress(ipv6)).isEqualTo(ipv6.getAddress().getHostAddress());
}
/**
* Test to inet socket address.
*/
@Test
public void testToInetSocketAddress() {
try {
NetUtil.toInetSocketAddress("23939:ks");
} catch (Exception e) {
assertThat(e).isInstanceOf(NumberFormatException.class);
}
}
/**
* Test to inet socket address 1.
*/
@Test
public void testToInetSocketAddress1() {
assertThat(NetUtil.toInetSocketAddress("kadfskl").getHostName()).isEqualTo("kadfskl");
}
/**
* Test to long.
*/
@Test
public void testToLong() {
try {
NetUtil.toLong("kdskdsfk");
} catch (Exception e) {
assertThat(e).isInstanceOf(NullPointerException.class);
}
}
/**
* Test to long 1.
*/
@Test
public void testToLong1() {
String[] split = "127.0.0.1".split("\\.");
long r = 0;
r = r | (Long.parseLong(split[0]) << 40);
r = r | (Long.parseLong(split[1]) << 32);
r = r | (Long.parseLong(split[2]) << 24);
r = r | (Long.parseLong(split[3]) << 16);
assertThat(NetUtil.toLong("127.0.0.1")).isEqualTo(r);
}
/**
* Test get local ip.
*/
@Test
public void testGetLocalIp() {
assertThat(NetUtil.getLocalIp()).isNotNull();
}
/**
* Test get local host.
*/
@Test
public void testGetLocalHost() {
assertThat(NetUtil.getLocalHost()).isNotNull();
}
/**
* Test get local address.
*/
@Test
public void testGetLocalAddress() {
assertThat(NetUtil.getLocalAddress()).isNotNull();
}
@Test
public void testIsValidIp() {
String localIp = "127.0.0.1";
String someIp = "8.210.212.91";
String someHostName = "seata.io";
String unknownHost = "knownHost";
assertThat(NetUtil.isValidIp(localIp, true)).isTrue();
assertThat(NetUtil.isValidIp(localIp, false)).isFalse();
assertThat(NetUtil.isValidIp(someIp, true)).isTrue();
assertThat(NetUtil.isValidIp(someIp, false)).isTrue();
assertThat(NetUtil.isValidIp(someHostName, true)).isTrue();
assertThat(NetUtil.isValidIp(someHostName, false)).isTrue();
assertThatThrownBy(() -> {
NetUtil.isValidIp(unknownHost, false);
}).isInstanceOf(RuntimeException.class).hasMessageContaining("UnknownHostException");
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
/**
* @author caioguedes
*/
public class NumberUtilsTest {
@Test
public void testToInReturnDefaultValueWithNull() {
Assertions.assertEquals(10, NumberUtils.toInt(null, 10));
}
@Test
public void testToInReturnDefaultValueWithFormatIsInvalid() {
Assertions.assertEquals(10, NumberUtils.toInt("nine", 10));
}
@Test
public void testToInReturnParsedValue() {
Assertions.assertEquals(10, NumberUtils.toInt("10", 9));
}
}

View File

@@ -0,0 +1,111 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class ReflectionUtilTest {
//Prevent jvm from optimizing final
public static final String testValue = (null != null ? "hello" : "hello");
@Test
public void testGetClassByName() throws ClassNotFoundException {
Assertions.assertEquals(String.class,
ReflectionUtil.getClassByName("java.lang.String"));
}
@Test
public void testGetFieldValue() throws
NoSuchFieldException, IllegalAccessException {
Assertions.assertEquals("d",
ReflectionUtil.getFieldValue(new DurationUtil(), "DAY_UNIT"));
Assertions.assertThrows(NoSuchFieldException.class,
() -> ReflectionUtil.getFieldValue(new Object(), "A1B2C3"));
}
@Test
public void testInvokeMethod() throws NoSuchMethodException,
IllegalAccessException, InvocationTargetException {
Assertions.assertEquals(0, ReflectionUtil.invokeMethod("", "length"));
Assertions.assertEquals(3,
ReflectionUtil.invokeMethod("foo", "length"));
Assertions.assertThrows(NoSuchMethodException.class,
() -> ReflectionUtil.invokeMethod("", "size"));
}
@Test
public void testInvokeMethod2() throws NoSuchMethodException,
IllegalAccessException, InvocationTargetException {
Assertions.assertEquals(0, ReflectionUtil
.invokeMethod("", "length", null, null));
Assertions.assertEquals(3, ReflectionUtil
.invokeMethod("foo", "length", null, null));
Assertions.assertThrows(NoSuchMethodException.class, () -> ReflectionUtil
.invokeMethod("", "size", null, null));
}
@Test
public void testInvokeMethod3() throws NoSuchMethodException,
IllegalAccessException, InvocationTargetException {
Assertions.assertEquals("0", ReflectionUtil.invokeStaticMethod(
String.class, "valueOf",
new Class<?>[]{int.class}, new Object[]{0}));
Assertions.assertEquals("123", ReflectionUtil.invokeStaticMethod(
String.class, "valueOf",
new Class<?>[]{int.class}, new Object[]{123}));
Assertions.assertThrows(NoSuchMethodException.class, () -> ReflectionUtil
.invokeStaticMethod(String.class, "size", null, null));
}
@Test
public void testGetMethod() throws NoSuchMethodException {
Assertions.assertEquals("public int java.lang.String.length()",
ReflectionUtil.getMethod(String.class, "length", null)
.toString());
Assertions.assertEquals("public char java.lang.String.charAt(int)",
ReflectionUtil.getMethod(String.class, "charAt",
new Class<?>[]{int.class}).toString());
Assertions.assertThrows(NoSuchMethodException.class,
() -> ReflectionUtil.getMethod(String.class, "size", null));
}
@Test
public void testGetInterfaces() {
Assertions.assertArrayEquals(new Object[]{Serializable.class},
ReflectionUtil.getInterfaces(Serializable.class).toArray());
Assertions.assertArrayEquals(new Object[]{
Serializable.class, Comparable.class, CharSequence.class},
ReflectionUtil.getInterfaces(String.class).toArray());
}
@Test
public void testModifyStaticFinalField() throws NoSuchFieldException, IllegalAccessException {
Assertions.assertEquals("hello", testValue);
ReflectionUtil.modifyStaticFinalField(ReflectionUtilTest.class, "testValue", "hello world");
Assertions.assertEquals("hello world", testValue);
}
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class SizeUtilTest {
@Test
void size2Long() {
assertThat(SizeUtil.size2Long("2k")).isEqualTo(2L * 1024);
assertThat(SizeUtil.size2Long("2m")).isEqualTo(2L * 1024 * 1024);
assertThat(SizeUtil.size2Long("2G")).isEqualTo(2L * 1024 * 1024 * 1024);
assertThat(SizeUtil.size2Long("2t")).isEqualTo(2L * 1024 * 1024 * 1024 * 1024);
}
}

View File

@@ -0,0 +1,35 @@
package io.seata.common.util;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class StringFormatUtilsTest {
@Test
void camelToUnderline() {
assertThat(StringFormatUtils.camelToUnderline(null)).isEqualTo("");
assertThat(StringFormatUtils.camelToUnderline(" ")).isEqualTo("");
assertThat(StringFormatUtils.camelToUnderline("abcDefGh")).isEqualTo("abc_def_gh");
}
@Test
void underlineToCamel() {
assertThat(StringFormatUtils.underlineToCamel(null)).isEqualTo("");
assertThat(StringFormatUtils.underlineToCamel(" ")).isEqualTo("");
assertThat(StringFormatUtils.underlineToCamel("abc_def_gh")).isEqualTo("abcDefGh");
}
@Test
void minusToCamel() {
assertThat(StringFormatUtils.minusToCamel(null)).isEqualTo("");
assertThat(StringFormatUtils.minusToCamel(" ")).isEqualTo("");
assertThat(StringFormatUtils.minusToCamel("abc-def-gh")).isEqualTo("abcDefGh");
}
@Test
void dotToCamel() {
assertThat(StringFormatUtils.dotToCamel(null)).isEqualTo("");
assertThat(StringFormatUtils.dotToCamel(" ")).isEqualTo("");
assertThat(StringFormatUtils.dotToCamel("abc.def.gh")).isEqualTo("abcDefGh");
}
}

View File

@@ -0,0 +1,112 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.common.util;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import io.seata.common.Constants;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertNull;
/**
* The type String utils test.
*
* @author Otis.z
* @author Geng Zhang
*/
public class StringUtilsTest {
/**
* Test is empty.
*/
@Test
public void testIsNullOrEmpty() {
assertThat(StringUtils.isNullOrEmpty(null)).isTrue();
assertThat(StringUtils.isNullOrEmpty("abc")).isFalse();
assertThat(StringUtils.isNullOrEmpty("")).isTrue();
assertThat(StringUtils.isNullOrEmpty(" ")).isFalse();
}
@Test
public void testInputStream2String() throws IOException {
assertNull(StringUtils.inputStream2String(null));
String data = "abc\n"
+ ":\"klsdf\n"
+ "2ks,x:\".,-3sd˚ø≤ø¬≥";
ByteArrayInputStream inputStream = new ByteArrayInputStream(data.getBytes(Constants.DEFAULT_CHARSET));
assertThat(StringUtils.inputStream2String(inputStream)).isEqualTo(data);
}
@Test
void inputStream2Bytes() {
assertNull(StringUtils.inputStream2Bytes(null));
String data = "abc\n"
+ ":\"klsdf\n"
+ "2ks,x:\".,-3sd˚ø≤ø¬≥";
byte[] bs = data.getBytes(Constants.DEFAULT_CHARSET);
ByteArrayInputStream inputStream = new ByteArrayInputStream(data.getBytes(Constants.DEFAULT_CHARSET));
assertThat(StringUtils.inputStream2Bytes(inputStream)).isEqualTo(bs);
}
@Test
void testEquals() {
Assertions.assertTrue(StringUtils.equals("1", "1"));
Assertions.assertFalse(StringUtils.equals("1", "2"));
Assertions.assertFalse(StringUtils.equals(null, "1"));
Assertions.assertFalse(StringUtils.equals("1", null));
Assertions.assertFalse(StringUtils.equals("", null));
Assertions.assertFalse(StringUtils.equals(null, ""));
}
@Test
void testEqualsIgnoreCase() {
Assertions.assertTrue(StringUtils.equalsIgnoreCase("a", "a"));
Assertions.assertTrue(StringUtils.equalsIgnoreCase("a", "A"));
Assertions.assertTrue(StringUtils.equalsIgnoreCase("A", "a"));
Assertions.assertFalse(StringUtils.equalsIgnoreCase("1", "2"));
Assertions.assertFalse(StringUtils.equalsIgnoreCase(null, "1"));
Assertions.assertFalse(StringUtils.equalsIgnoreCase("1", null));
Assertions.assertFalse(StringUtils.equalsIgnoreCase("", null));
Assertions.assertFalse(StringUtils.equalsIgnoreCase(null, ""));
}
@Test
void testCycleDependency() throws StackOverflowError{
StringUtils.toString(CycleDependency.A);
}
static class CycleDependency {
public static final CycleDependency A = new CycleDependency("a");
public static final CycleDependency B = new CycleDependency("b");
private String s;
private CycleDependency(String s) {
this.s = s;
}
@Override
public String toString() {
return "{" +
"s='" + s + '\'' +
'}';
}
}
}

View File

@@ -0,0 +1,19 @@
#
# Copyright 1999-2019 Seata.io Group.
#
# 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.
#
io.seata.common.loader.EnglishHello
io.seata.common.loader.LatinHello

View File

@@ -0,0 +1,19 @@
#
# Copyright 1999-2019 Seata.io Group.
#
# 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.
#
io.seata.common.loader.FrenchHello
io.seata.common.loader.EnglishHello
io.seata.common.loader.LatinHello

View File

@@ -0,0 +1,19 @@
#
#
# Copyright 1999-2019 Seata.io Group.
#
# 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.
#
#
io.seata.common.loader.ChineseHello

41
compressor/pom.xml Normal file
View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 1999-2019 Seata.io Group.
~
~ 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.
-->
<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>io.seata</groupId>
<artifactId>seata-parent</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>seata-compressor</artifactId>
<packaging>pom</packaging>
<name>seata-compressor ${project.version}</name>
<modules>
<module>seata-compressor-all</module>
<module>seata-compressor-gzip</module>
<module>seata-compressor-zip</module>
<module>seata-compressor-7z</module>
<module>seata-compressor-bzip2</module>
<module>seata-compressor-lz4</module>
<module>seata-compressor-deflater</module>
</modules>
</project>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 1999-2019 Seata.io Group.
~
~ 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.
-->
<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>io.seata</groupId>
<artifactId>seata-compressor</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>seata-compressor-7z</artifactId>
<packaging>jar</packaging>
<name>seata-compressor-7z ${project.version}</name>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>seata-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.tukaani</groupId>
<artifactId>xz</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,39 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.compressor.sevenz;
import io.seata.common.loader.LoadLevel;
import io.seata.core.compressor.Compressor;
/**
* the SevenZ Compressor
*
* @author ph3636
*/
@LoadLevel(name = "SEVENZ")
public class SevenZCompressor implements Compressor {
@Override
public byte[] compress(byte[] bytes) {
return SevenZUtil.compress(bytes);
}
@Override
public byte[] decompress(byte[] bytes) {
return SevenZUtil.decompress(bytes);
}
}

View File

@@ -0,0 +1,73 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.compressor.sevenz;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
import org.apache.commons.compress.archivers.sevenz.SevenZOutputFile;
import org.apache.commons.compress.utils.SeekableInMemoryByteChannel;
/**
* the SevenZ Util
*
* @author ph3636
*/
public class SevenZUtil {
private static final int BUFFER_SIZE = 8192;
public static byte[] compress(byte[] bytes) {
if (bytes == null) {
throw new NullPointerException("bytes is null");
}
SeekableInMemoryByteChannel channel = new SeekableInMemoryByteChannel();
try (SevenZOutputFile z7z = new SevenZOutputFile(channel)) {
SevenZArchiveEntry entry = new SevenZArchiveEntry();
entry.setName("sevenZip");
entry.setSize(bytes.length);
z7z.putArchiveEntry(entry);
z7z.write(bytes);
z7z.closeArchiveEntry();
z7z.finish();
return channel.array();
} catch (IOException e) {
throw new RuntimeException("SevenZ compress error", e);
}
}
public static byte[] decompress(byte[] bytes) {
if (bytes == null) {
throw new NullPointerException("bytes is null");
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
SeekableInMemoryByteChannel channel = new SeekableInMemoryByteChannel(bytes);
try (SevenZFile sevenZFile = new SevenZFile(channel)) {
byte[] buffer = new byte[BUFFER_SIZE];
while (sevenZFile.getNextEntry() != null) {
int n;
while ((n = sevenZFile.read(buffer)) > -1) {
out.write(buffer, 0, n);
}
}
return out.toByteArray();
} catch (IOException e) {
throw new RuntimeException("SevenZ decompress error", e);
}
}
}

View File

@@ -0,0 +1 @@
io.seata.compressor.sevenz.SevenZCompressor

View File

@@ -0,0 +1,36 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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 io.seata.compressor.sevenz;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
/**
* the SevenZ Compressor test
*
* @author ph3636
*/
public class SevenZCompressorTest {
@Test
public void testCompressAndDecompress() {
SevenZCompressor compressor = new SevenZCompressor();
byte[] bytes = "aa".getBytes();
bytes = compressor.compress(bytes);
bytes = compressor.decompress(bytes);
Assertions.assertEquals(new String(bytes), "aa");
}
}

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