chore(project): 添加项目配置文件和忽略规则
- 添加 Babel 配置文件支持 ES6+ 语法转换 - 添加 ESLint 忽略规则和配置文件 - 添加 Git 忽略规则文件 - 添加 Travis CI 配置文件 - 添加 1.4.2 版本变更日志文件 - 添加 Helm 图表辅助模板文件 - 添加 Helm 忽略规则文件
This commit is contained in:
43
common/pom.xml
Normal file
43
common/pom.xml
Normal 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>
|
||||
160
common/src/main/java/io/seata/common/Constants.java
Normal file
160
common/src/main/java/io/seata/common/Constants.java
Normal 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";
|
||||
|
||||
}
|
||||
122
common/src/main/java/io/seata/common/DefaultValues.java
Normal file
122
common/src/main/java/io/seata/common/DefaultValues.java
Normal 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;
|
||||
}
|
||||
89
common/src/main/java/io/seata/common/XID.java
Normal file
89
common/src/main/java/io/seata/common/XID.java
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
35
common/src/main/java/io/seata/common/executor/Callback.java
Normal file
35
common/src/main/java/io/seata/common/executor/Callback.java
Normal 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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
52
common/src/main/java/io/seata/common/loader/LoadLevel.java
Normal file
52
common/src/main/java/io/seata/common/loader/LoadLevel.java
Normal 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;
|
||||
}
|
||||
34
common/src/main/java/io/seata/common/loader/Scope.java
Normal file
34
common/src/main/java/io/seata/common/loader/Scope.java
Normal 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
|
||||
|
||||
}
|
||||
93
common/src/main/java/io/seata/common/rpc/RpcStatus.java
Normal file
93
common/src/main/java/io/seata/common/rpc/RpcStatus.java
Normal 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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
154
common/src/main/java/io/seata/common/util/BeanUtils.java
Normal file
154
common/src/main/java/io/seata/common/util/BeanUtils.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
108
common/src/main/java/io/seata/common/util/BlobUtils.java
Normal file
108
common/src/main/java/io/seata/common/util/BlobUtils.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
280
common/src/main/java/io/seata/common/util/CollectionUtils.java
Normal file
280
common/src/main/java/io/seata/common/util/CollectionUtils.java
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
93
common/src/main/java/io/seata/common/util/CompressUtil.java
Normal file
93
common/src/main/java/io/seata/common/util/CompressUtil.java
Normal 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;
|
||||
}
|
||||
}
|
||||
142
common/src/main/java/io/seata/common/util/ConfigTools.java
Normal file
142
common/src/main/java/io/seata/common/util/ConfigTools.java
Normal 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();
|
||||
}
|
||||
|
||||
}
|
||||
74
common/src/main/java/io/seata/common/util/DurationUtil.java
Normal file
74
common/src/main/java/io/seata/common/util/DurationUtil.java
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
48
common/src/main/java/io/seata/common/util/IOUtil.java
Normal file
48
common/src/main/java/io/seata/common/util/IOUtil.java
Normal 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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
187
common/src/main/java/io/seata/common/util/IdWorker.java
Normal file
187
common/src/main/java/io/seata/common/util/IdWorker.java
Normal 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);
|
||||
}
|
||||
}
|
||||
35
common/src/main/java/io/seata/common/util/LambdaUtils.java
Normal file
35
common/src/main/java/io/seata/common/util/LambdaUtils.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
250
common/src/main/java/io/seata/common/util/NetUtil.java
Normal file
250
common/src/main/java/io/seata/common/util/NetUtil.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
63
common/src/main/java/io/seata/common/util/NumberUtils.java
Normal file
63
common/src/main/java/io/seata/common/util/NumberUtils.java
Normal 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;
|
||||
}
|
||||
}
|
||||
211
common/src/main/java/io/seata/common/util/ReflectionUtil.java
Normal file
211
common/src/main/java/io/seata/common/util/ReflectionUtil.java
Normal 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);
|
||||
}
|
||||
}
|
||||
60
common/src/main/java/io/seata/common/util/SizeUtil.java
Normal file
60
common/src/main/java/io/seata/common/util/SizeUtil.java
Normal 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
107
common/src/main/java/io/seata/common/util/StringFormatUtils.java
Normal file
107
common/src/main/java/io/seata/common/util/StringFormatUtils.java
Normal 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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
265
common/src/main/java/io/seata/common/util/StringUtils.java
Normal file
265
common/src/main/java/io/seata/common/util/StringUtils.java
Normal 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);
|
||||
}
|
||||
}
|
||||
63
common/src/test/java/io/seata/common/BranchDO.java
Normal file
63
common/src/test/java/io/seata/common/BranchDO.java
Normal 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;
|
||||
}
|
||||
}
|
||||
68
common/src/test/java/io/seata/common/XIDTest.java
Normal file
68
common/src/test/java/io/seata/common/XIDTest.java
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
103
common/src/test/java/io/seata/common/exception/Message.java
Normal file
103
common/src/test/java/io/seata/common/exception/Message.java
Normal 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");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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!";
|
||||
}
|
||||
}
|
||||
@@ -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!";
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
30
common/src/test/java/io/seata/common/loader/FrenchHello.java
Normal file
30
common/src/test/java/io/seata/common/loader/FrenchHello.java
Normal 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";
|
||||
}
|
||||
}
|
||||
30
common/src/test/java/io/seata/common/loader/Hello.java
Normal file
30
common/src/test/java/io/seata/common/loader/Hello.java
Normal 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();
|
||||
}
|
||||
29
common/src/test/java/io/seata/common/loader/LatinHello.java
Normal file
29
common/src/test/java/io/seata/common/loader/LatinHello.java
Normal 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á.";
|
||||
}
|
||||
}
|
||||
58
common/src/test/java/io/seata/common/rpc/RpcStatusTest.java
Normal file
58
common/src/test/java/io/seata/common/rpc/RpcStatusTest.java
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
87
common/src/test/java/io/seata/common/util/BeanUtilsTest.java
Normal file
87
common/src/test/java/io/seata/common/util/BeanUtilsTest.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
76
common/src/test/java/io/seata/common/util/BlobUtilsTest.java
Normal file
76
common/src/test/java/io/seata/common/util/BlobUtilsTest.java
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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}));
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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"));
|
||||
|
||||
}
|
||||
}
|
||||
73
common/src/test/java/io/seata/common/util/IOUtilTest.java
Normal file
73
common/src/test/java/io/seata/common/util/IOUtilTest.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
46
common/src/test/java/io/seata/common/util/IdWorkerTest.java
Normal file
46
common/src/test/java/io/seata/common/util/IdWorkerTest.java
Normal 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");
|
||||
}
|
||||
}
|
||||
184
common/src/test/java/io/seata/common/util/NetUtilTest.java
Normal file
184
common/src/test/java/io/seata/common/util/NetUtilTest.java
Normal 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");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
30
common/src/test/java/io/seata/common/util/SizeUtilTest.java
Normal file
30
common/src/test/java/io/seata/common/util/SizeUtilTest.java
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
112
common/src/test/java/io/seata/common/util/StringUtilsTest.java
Normal file
112
common/src/test/java/io/seata/common/util/StringUtilsTest.java
Normal 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 + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user