Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
L
loit-build-common
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
loit-Infrastructure
loit-build-common
Commits
c690f89d
提交
c690f89d
authored
2月 27, 2020
作者:
陈世营
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
leaf zookeeper分布式ID
上级
b74f828d
隐藏空白字符变更
内嵌
并排
正在显示
25 个修改的文件
包含
1687 行增加
和
4 行删除
+1687
-4
pom.xml
loit-build-commom-parent/pom.xml
+45
-4
pom.xml
loit-build-component/loit-keygen-leaf-zk/pom.xml
+53
-0
LeafSegmentLeafKeyGenerator.java
...it/component/keygen/leaf/LeafSegmentLeafKeyGenerator.java
+198
-0
NewInstanceServiceLoader.java
.../component/keygen/leaf/core/NewInstanceServiceLoader.java
+58
-0
LeafConfigurationException.java
...eygen/leaf/core/exception/LeafConfigurationException.java
+29
-0
RegistryCenterException.java
...t/keygen/leaf/core/exception/RegistryCenterException.java
+36
-0
DataChangedEvent.java
...component/keygen/leaf/core/listener/DataChangedEvent.java
+27
-0
DataChangedEventListener.java
...t/keygen/leaf/core/listener/DataChangedEventListener.java
+16
-0
RegistryCenter.java
...m/loit/component/keygen/leaf/core/reg/RegistryCenter.java
+112
-0
RegistryCenterConfiguration.java
...ent/keygen/leaf/core/reg/RegistryCenterConfiguration.java
+58
-0
RegistryCenterServiceLoader.java
...ent/keygen/leaf/core/reg/RegistryCenterServiceLoader.java
+33
-0
TypeBasedSPI.java
...com/loit/component/keygen/leaf/core/spi/TypeBasedSPI.java
+30
-0
TypeBasedSPIConfiguration.java
...onent/keygen/leaf/core/spi/TypeBasedSPIConfiguration.java
+30
-0
TypeBasedSPIServiceLoader.java
...onent/keygen/leaf/core/spi/TypeBasedSPIServiceLoader.java
+67
-0
LeafKeyGenerator.java
...m/loit/component/keygen/leaf/keygen/LeafKeyGenerator.java
+18
-0
package-info.java
...ain/java/com/loit/component/keygen/leaf/package-info.java
+2
-0
CuratorZookeeperExceptionHandler.java
...nent/keygen/leaf/zk/CuratorZookeeperExceptionHandler.java
+43
-0
CuratorZookeeperRegistryCenter.java
...ponent/keygen/leaf/zk/CuratorZookeeperRegistryCenter.java
+292
-0
com.loit.component.keygen.leaf.core.reg.RegistryCenter
...es/com.loit.component.keygen.leaf.core.reg.RegistryCenter
+1
-0
LeafSegmentLeafKeyGeneratorTest.java
...omponent/keygen/leaf/LeafSegmentLeafKeyGeneratorTest.java
+312
-0
package-info.java
...est/java/com/loit/component/keygen/leaf/package-info.java
+2
-0
CuratorZookeeperRegistryCenterTest.java
...nt/keygen/leaf/zk/CuratorZookeeperRegistryCenterTest.java
+84
-0
ThirdTestRegistryCenter.java
...oit/component/keygen/leaf/zk/ThirdTestRegistryCenter.java
+88
-0
EmbedTestingServer.java
...oit/component/keygen/leaf/zk/util/EmbedTestingServer.java
+51
-0
pom.xml
loit-build-component/pom.xml
+2
-0
没有找到文件。
loit-build-commom-parent/pom.xml
浏览文件 @
c690f89d
...
...
@@ -35,14 +35,18 @@
<tomcat-embed-core.version>
8.5.34
</tomcat-embed-core.version>
<jacoco.version>
0.8.3
</jacoco.version>
<curator.version>
2.10.0
</curator.version>
<junit.version>
4.12
</junit.version>
<maven-compiler-plugin.version>
3.7.0
</maven-compiler-plugin.version>
<shardingsphere.version>
5.0.0-RC1-SNAPSHOT
</shardingsphere.version>
<shardingsphere.spi.impl.version>
5.0.0-RC1-SNAPSHOT
</shardingsphere.spi.impl.version>
<maven-compiler-plugin.version>
3.7.0
</maven-compiler-plugin.version>
<lombok.version>
1.18.8
</lombok.version>
<leaf-core.version>
1.0.1
</leaf-core.version>
</properties>
<dependencyManagement>
...
...
@@ -223,8 +227,45 @@
<artifactId>
sharding-orchestration-reg-etcd
</artifactId>
<version>
${shardingsphere.spi.impl.version}
</version>
</dependency>
<dependency>
<groupId>
junit
</groupId>
<artifactId>
junit
</artifactId>
<version>
${junit.version}
</version>
<scope>
test
</scope>
</dependency>
<!--shardingsphere end-->
<!--zookeeper begin-->
<dependency>
<groupId>
org.apache.curator
</groupId>
<artifactId>
curator-framework
</artifactId>
<version>
${curator.version}
</version>
</dependency>
<dependency>
<groupId>
org.apache.curator
</groupId>
<artifactId>
curator-client
</artifactId>
<version>
${curator.version}
</version>
<exclusions>
<exclusion>
<artifactId>
netty
</artifactId>
<groupId>
io.netty
</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>
org.apache.curator
</groupId>
<artifactId>
curator-recipes
</artifactId>
<version>
${curator.version}
</version>
</dependency>
<dependency>
<groupId>
org.apache.curator
</groupId>
<artifactId>
curator-test
</artifactId>
<version>
${curator.version}
</version>
<scope>
test
</scope>
</dependency>
<!--zookeeper end-->
</dependencies>
</dependencyManagement>
...
...
@@ -271,8 +312,8 @@
</plugin>
</plugins>
</build>
<distributionManagement>
<distributionManagement>
<repository>
<id>
nexus-releases
</id>
<name>
Nexus Release Repository
</name>
...
...
loit-build-component/loit-keygen-leaf-zk/pom.xml
0 → 100644
浏览文件 @
c690f89d
<?xml version="1.0" encoding="UTF-8"?>
<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>
<artifactId>
loit-build-component
</artifactId>
<groupId>
com.timeloit.project
</groupId>
<version>
1.0-SNAPSHOT
</version>
</parent>
<modelVersion>
4.0.0
</modelVersion>
<artifactId>
loit-keygen-leaf-zk
</artifactId>
<dependencies>
<dependency>
<groupId>
com.google.guava
</groupId>
<artifactId>
guava
</artifactId>
</dependency>
<dependency>
<groupId>
org.projectlombok
</groupId>
<artifactId>
lombok
</artifactId>
<version>
${lombok.version}
</version>
<scope>
provided
</scope>
</dependency>
<dependency>
<groupId>
junit
</groupId>
<artifactId>
junit
</artifactId>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
org.apache.curator
</groupId>
<artifactId>
curator-framework
</artifactId>
</dependency>
<dependency>
<groupId>
org.apache.curator
</groupId>
<artifactId>
curator-client
</artifactId>
</dependency>
<dependency>
<groupId>
org.apache.curator
</groupId>
<artifactId>
curator-recipes
</artifactId>
</dependency>
<dependency>
<groupId>
org.apache.curator
</groupId>
<artifactId>
curator-test
</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
loit-build-component/loit-keygen-leaf-zk/src/main/java/com/loit/component/keygen/leaf/LeafSegmentLeafKeyGenerator.java
0 → 100644
浏览文件 @
c690f89d
package
com
.
loit
.
component
.
keygen
.
leaf
;
import
com.google.common.base.Preconditions
;
import
com.google.common.base.Strings
;
import
com.loit.component.keygen.leaf.core.reg.RegistryCenter
;
import
com.loit.component.keygen.leaf.core.reg.RegistryCenterConfiguration
;
import
com.loit.component.keygen.leaf.core.reg.RegistryCenterServiceLoader
;
import
com.loit.component.keygen.leaf.keygen.LeafKeyGenerator
;
import
lombok.Getter
;
import
lombok.Setter
;
import
lombok.SneakyThrows
;
import
java.util.Properties
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.SynchronousQueue
;
/**
* Key generator implemented by leaf segment algorithms.
*
* @author wangguangyuan
*/
public
final
class
LeafSegmentLeafKeyGenerator
implements
LeafKeyGenerator
{
private
static
final
String
DEFAULT_NAMESPACE
=
"leaf_segment"
;
private
static
final
String
DEFAULT_STEP
=
"10000"
;
private
static
final
String
DEFAULT_INITIAL_VALUE
=
"1"
;
private
static
final
String
DEFAULT_REGISTRY_CENTER
=
"zookeeper"
;
private
static
final
String
SLANTING_BAR
=
"/"
;
private
static
final
String
REGULAR_PATTERN
=
"^((?!/).)*$"
;
private
final
ExecutorService
incrementCacheIdExecutor
;
private
final
SynchronousQueue
<
Long
>
cacheIdQueue
;
private
RegistryCenter
leafRegistryCenter
;
private
long
id
;
private
long
step
;
@Getter
@Setter
private
Properties
properties
=
new
Properties
();
public
LeafSegmentLeafKeyGenerator
()
{
incrementCacheIdExecutor
=
Executors
.
newSingleThreadExecutor
();
cacheIdQueue
=
new
SynchronousQueue
<>();
}
@Override
public
String
getType
()
{
return
"LEAF_SEGMENT"
;
}
@Override
public
synchronized
Comparable
<?>
generateKey
()
{
String
leafKey
=
getLeafKey
();
if
(
null
==
leafRegistryCenter
)
{
initLeafSegmentKeyGenerator
(
leafKey
);
}
else
{
increaseIdWhenLeafKeyStoredInCenter
(
leafKey
);
}
return
id
;
}
private
void
initLeafSegmentKeyGenerator
(
final
String
leafKey
)
{
RegistryCenterConfiguration
leafConfiguration
=
getRegistryCenterConfiguration
();
leafRegistryCenter
=
new
RegistryCenterServiceLoader
().
load
(
leafConfiguration
);
step
=
getStep
();
id
=
initializeId
(
leafKey
);
initializeLeafKeyInCenter
(
leafKey
,
id
,
step
);
initializeCacheIdAsynchronous
(
id
,
step
);
}
private
void
increaseIdWhenLeafKeyStoredInCenter
(
final
String
leafKey
)
{
if
((
id
%
step
)
==
0
)
{
id
=
tryTakeCacheId
();
incrementCacheIdAsynchronous
(
leafKey
,
step
-
(
id
%
step
));
}
++
id
;
}
private
long
initializeId
(
final
String
leafKey
)
{
if
(
leafRegistryCenter
.
isExisted
(
leafKey
))
{
return
Long
.
parseLong
(
leafRegistryCenter
.
getDirectly
(
leafKey
))
+
1
;
}
else
{
return
getInitialValue
();
}
}
private
void
initializeLeafKeyInCenter
(
final
String
leafKey
,
final
long
id
,
final
long
step
)
{
leafRegistryCenter
.
initLock
(
leafKey
);
while
(!
leafRegistryCenter
.
tryLock
())
{
continue
;
}
leafRegistryCenter
.
persist
(
leafKey
,
String
.
valueOf
(
id
+
step
-
id
%
step
));
leafRegistryCenter
.
tryRelease
();
}
private
void
initializeCacheIdAsynchronous
(
final
long
id
,
final
long
step
)
{
incrementCacheIdExecutor
.
execute
(
new
Runnable
()
{
@Override
public
void
run
()
{
tryPutCacheId
(
id
+
step
-
id
%
step
);
}
});
}
private
void
incrementCacheIdAsynchronous
(
final
String
leafKey
,
final
long
step
)
{
incrementCacheIdExecutor
.
execute
(
new
Runnable
()
{
@Override
public
void
run
()
{
long
newId
=
incrementCacheId
(
leafKey
,
step
);
tryPutCacheId
(
newId
);
}
});
}
private
RegistryCenterConfiguration
getRegistryCenterConfiguration
()
{
RegistryCenterConfiguration
result
=
new
RegistryCenterConfiguration
(
getRegistryCenterType
(),
properties
);
result
.
setNamespace
(
DEFAULT_NAMESPACE
);
result
.
setServerLists
(
getServerList
());
result
.
setDigest
(
getDigest
());
return
result
;
}
@SneakyThrows
private
long
incrementCacheId
(
final
String
leafKey
,
final
long
step
)
{
while
(!
leafRegistryCenter
.
tryLock
())
{
continue
;
}
long
result
=
updateCacheIdInCenter
(
leafKey
,
step
);
leafRegistryCenter
.
tryRelease
();
return
result
;
}
private
long
updateCacheIdInCenter
(
final
String
leafKey
,
final
long
step
)
{
String
cacheIdInString
=
leafRegistryCenter
.
getDirectly
(
leafKey
);
if
(
Strings
.
isNullOrEmpty
(
cacheIdInString
))
{
return
Long
.
MIN_VALUE
;
}
long
cacheId
=
Long
.
parseLong
(
cacheIdInString
);
long
result
=
cacheId
+
step
;
leafRegistryCenter
.
update
(
leafKey
,
String
.
valueOf
(
result
));
return
result
;
}
@SneakyThrows
private
void
tryPutCacheId
(
final
long
id
)
{
cacheIdQueue
.
put
(
id
);
}
@SneakyThrows
private
long
tryTakeCacheId
()
{
return
cacheIdQueue
.
take
();
}
private
long
getStep
()
{
long
result
=
Long
.
parseLong
(
properties
.
getProperty
(
"step"
,
DEFAULT_STEP
));
Preconditions
.
checkArgument
(
result
>
0L
&&
result
<
Long
.
MAX_VALUE
);
return
result
;
}
private
long
getInitialValue
()
{
long
result
=
Long
.
parseLong
(
properties
.
getProperty
(
"initialValue"
,
DEFAULT_INITIAL_VALUE
));
Preconditions
.
checkArgument
(
result
>=
0L
&&
result
<
Long
.
MAX_VALUE
);
return
result
;
}
private
String
getLeafKey
()
{
String
leafKey
=
properties
.
getProperty
(
"leafKey"
);
Preconditions
.
checkArgument
(!
Strings
.
isNullOrEmpty
(
leafKey
));
Preconditions
.
checkArgument
(
leafKey
.
matches
(
REGULAR_PATTERN
));
return
SLANTING_BAR
+
leafKey
;
}
private
String
getServerList
()
{
String
result
=
properties
.
getProperty
(
"serverList"
);
Preconditions
.
checkArgument
(!
Strings
.
isNullOrEmpty
(
result
));
return
result
;
}
private
String
getDigest
()
{
return
properties
.
getProperty
(
"digest"
);
}
private
String
getRegistryCenterType
()
{
return
properties
.
getProperty
(
"registryCenterType"
,
DEFAULT_REGISTRY_CENTER
);
}
}
loit-build-component/loit-keygen-leaf-zk/src/main/java/com/loit/component/keygen/leaf/core/NewInstanceServiceLoader.java
0 → 100644
浏览文件 @
c690f89d
package
com
.
loit
.
component
.
keygen
.
leaf
.
core
;
import
lombok.AccessLevel
;
import
lombok.NoArgsConstructor
;
import
lombok.SneakyThrows
;
import
java.util.*
;
/**
* SPI service loader for new instance for every call.
*/
@NoArgsConstructor
(
access
=
AccessLevel
.
PRIVATE
)
public
final
class
NewInstanceServiceLoader
{
private
static
final
Map
<
Class
,
Collection
<
Class
<?>>>
SERVICE_MAP
=
new
HashMap
<>();
/**
* Register SPI service into map for new instance.
*
* @param service service type
* @param <T> type of service
*/
public
static
<
T
>
void
register
(
final
Class
<
T
>
service
)
{
for
(
T
each
:
ServiceLoader
.
load
(
service
))
{
registerServiceClass
(
service
,
each
);
}
}
@SuppressWarnings
(
"unchecked"
)
private
static
<
T
>
void
registerServiceClass
(
final
Class
<
T
>
service
,
final
T
instance
)
{
Collection
<
Class
<?>>
serviceClasses
=
SERVICE_MAP
.
get
(
service
);
if
(
null
==
serviceClasses
)
{
serviceClasses
=
new
LinkedHashSet
<>();
}
serviceClasses
.
add
(
instance
.
getClass
());
SERVICE_MAP
.
put
(
service
,
serviceClasses
);
}
/**
* New service instances.
*
* @param service service class
* @param <T> type of service
* @return service instances
*/
@SneakyThrows
@SuppressWarnings
(
"unchecked"
)
public
static
<
T
>
Collection
<
T
>
newServiceInstances
(
final
Class
<
T
>
service
)
{
Collection
<
T
>
result
=
new
LinkedList
<>();
if
(
null
==
SERVICE_MAP
.
get
(
service
))
{
return
result
;
}
for
(
Class
<?>
each
:
SERVICE_MAP
.
get
(
service
))
{
result
.
add
((
T
)
each
.
newInstance
());
}
return
result
;
}
}
loit-build-component/loit-keygen-leaf-zk/src/main/java/com/loit/component/keygen/leaf/core/exception/LeafConfigurationException.java
0 → 100644
浏览文件 @
c690f89d
package
com
.
loit
.
component
.
keygen
.
leaf
.
core
.
exception
;
/**
* Sharding rule exception.
*
*/
public
final
class
LeafConfigurationException
extends
RuntimeException
{
private
static
final
long
serialVersionUID
=
-
1360264079938958332L
;
/**
* Constructs an exception with formatted error message and arguments.
*
* @param errorMessage formatted error message
* @param args arguments of error message
*/
public
LeafConfigurationException
(
final
String
errorMessage
,
final
Object
...
args
)
{
super
(
String
.
format
(
errorMessage
,
args
));
}
/**
* Constructs an exception with cause exception.
*
* @param cause cause exception
*/
public
LeafConfigurationException
(
final
Exception
cause
)
{
super
(
cause
);
}
}
loit-build-component/loit-keygen-leaf-zk/src/main/java/com/loit/component/keygen/leaf/core/exception/RegistryCenterException.java
0 → 100644
浏览文件 @
c690f89d
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
loit
.
component
.
keygen
.
leaf
.
core
.
exception
;
/**
* Registry center exception.
*
* @author zhangliang
*/
public
final
class
RegistryCenterException
extends
RuntimeException
{
private
static
final
long
serialVersionUID
=
-
6417179023552012152L
;
public
RegistryCenterException
(
final
String
errorMessage
,
final
Object
...
args
)
{
super
(
String
.
format
(
errorMessage
,
args
));
}
public
RegistryCenterException
(
final
Exception
cause
)
{
super
(
cause
);
}
}
loit-build-component/loit-keygen-leaf-zk/src/main/java/com/loit/component/keygen/leaf/core/listener/DataChangedEvent.java
0 → 100644
浏览文件 @
c690f89d
package
com
.
loit
.
component
.
keygen
.
leaf
.
core
.
listener
;
import
lombok.Getter
;
import
lombok.RequiredArgsConstructor
;
/**
* Data changed event.
*
*/
@RequiredArgsConstructor
@Getter
public
final
class
DataChangedEvent
{
private
final
String
key
;
private
final
String
value
;
private
final
ChangedType
changedType
;
/**
* Data changed type.
*/
public
enum
ChangedType
{
UPDATED
,
DELETED
,
IGNORED
}
}
loit-build-component/loit-keygen-leaf-zk/src/main/java/com/loit/component/keygen/leaf/core/listener/DataChangedEventListener.java
0 → 100644
浏览文件 @
c690f89d
package
com
.
loit
.
component
.
keygen
.
leaf
.
core
.
listener
;
/**
* Listener for data changed event.
*
* @author junxiong
*/
public
interface
DataChangedEventListener
{
/**
* Fire when data changed.
*
* @param dataChangedEvent data changed event
*/
void
onChange
(
DataChangedEvent
dataChangedEvent
);
}
loit-build-component/loit-keygen-leaf-zk/src/main/java/com/loit/component/keygen/leaf/core/reg/RegistryCenter.java
0 → 100644
浏览文件 @
c690f89d
package
com
.
loit
.
component
.
keygen
.
leaf
.
core
.
reg
;
import
com.loit.component.keygen.leaf.core.listener.DataChangedEventListener
;
import
com.loit.component.keygen.leaf.core.spi.TypeBasedSPI
;
import
java.util.List
;
/**
* Registry center.
*/
public
interface
RegistryCenter
extends
TypeBasedSPI
{
/**
* Initialize registry center.
*
* @param config registry center configuration
*/
void
init
(
RegistryCenterConfiguration
config
);
/**
* Get data from registry center.
*
* <p>Maybe use cache if existed.</p>
*
* @param key key of data
* @return value of data
*/
String
get
(
String
key
);
/**
* Get data from registry center directly.
*
* <p>Cannot use cache.</p>
*
* @param key key of data
* @return value of data
*/
String
getDirectly
(
String
key
);
/**
* Judge data is existed or not.
*
* @param key key of data
* @return data is existed or not
*/
boolean
isExisted
(
String
key
);
/**
* Get node's sub-nodes list.
*
* @param key key of data
* @return sub-nodes name list
*/
List
<
String
>
getChildrenKeys
(
String
key
);
/**
* Persist data.
*
* @param key key of data
* @param value value of data
*/
void
persist
(
String
key
,
String
value
);
/**
* Update data.
*
* @param key key of data
* @param value value of data
*/
void
update
(
String
key
,
String
value
);
/**
* Persist ephemeral data.
*
* @param key key of data
* @param value value of data
*/
void
persistEphemeral
(
String
key
,
String
value
);
/**
* Watch key or path of the registry.
*
* @param key key of data
* @param dataChangedEventListener data changed event listener
*/
void
watch
(
String
key
,
DataChangedEventListener
dataChangedEventListener
);
/**
* Close.
*/
void
close
();
/**
* Initialize the lock of the key.
*
* @param key key of data
*/
void
initLock
(
String
key
);
/**
* Try to get the lock of the key.
*
* @return get the lock or not
*/
boolean
tryLock
();
/**
* Try to release the lock of the key.
*
*/
void
tryRelease
();
}
loit-build-component/loit-keygen-leaf-zk/src/main/java/com/loit/component/keygen/leaf/core/reg/RegistryCenterConfiguration.java
0 → 100644
浏览文件 @
c690f89d
package
com
.
loit
.
component
.
keygen
.
leaf
.
core
.
reg
;
import
com.loit.component.keygen.leaf.core.spi.TypeBasedSPIConfiguration
;
import
lombok.Getter
;
import
lombok.Setter
;
import
java.util.Properties
;
/**
* Registry center configuration.
*/
@Getter
@Setter
public
final
class
RegistryCenterConfiguration
extends
TypeBasedSPIConfiguration
{
/**
* Server list of registry center.
*/
private
String
serverLists
;
/**
* Namespace of registry center.
*/
private
String
namespace
;
/**
* Digest of registry center.
*/
private
String
digest
;
/**
* Operation timeout time in milliseconds.
*/
private
int
operationTimeoutMilliseconds
=
500
;
/**
* Max number of times to retry.
*/
private
int
maxRetries
=
3
;
/**
* Time interval in milliseconds on each retry.
*/
private
int
retryIntervalMilliseconds
=
500
;
/**
* Time to live in seconds of ephemeral keys.
*/
private
int
timeToLiveSeconds
=
60
;
public
RegistryCenterConfiguration
(
final
String
type
)
{
super
(
type
);
}
public
RegistryCenterConfiguration
(
final
String
type
,
final
Properties
properties
)
{
super
(
type
,
properties
);
}
}
loit-build-component/loit-keygen-leaf-zk/src/main/java/com/loit/component/keygen/leaf/core/reg/RegistryCenterServiceLoader.java
0 → 100644
浏览文件 @
c690f89d
package
com
.
loit
.
component
.
keygen
.
leaf
.
core
.
reg
;
import
com.google.common.base.Preconditions
;
import
com.loit.component.keygen.leaf.core.NewInstanceServiceLoader
;
import
com.loit.component.keygen.leaf.core.spi.TypeBasedSPIServiceLoader
;
/**
* Registry center loader from SPI.
*/
public
final
class
RegistryCenterServiceLoader
extends
TypeBasedSPIServiceLoader
<
RegistryCenter
>
{
static
{
NewInstanceServiceLoader
.
register
(
RegistryCenter
.
class
);
}
public
RegistryCenterServiceLoader
()
{
super
(
RegistryCenter
.
class
);
}
/**
* Load registry center from SPI.
*
* @param regCenterConfig registry center configuration
* @return registry center
*/
public
RegistryCenter
load
(
final
RegistryCenterConfiguration
regCenterConfig
)
{
Preconditions
.
checkNotNull
(
regCenterConfig
,
"Registry center configuration cannot be null."
);
RegistryCenter
result
=
newService
(
regCenterConfig
.
getType
(),
regCenterConfig
.
getProperties
());
result
.
init
(
regCenterConfig
);
return
result
;
}
}
loit-build-component/loit-keygen-leaf-zk/src/main/java/com/loit/component/keygen/leaf/core/spi/TypeBasedSPI.java
0 → 100644
浏览文件 @
c690f89d
package
com
.
loit
.
component
.
keygen
.
leaf
.
core
.
spi
;
import
java.util.Properties
;
/**
* Base algorithm SPI.
*/
public
interface
TypeBasedSPI
{
/**
* Get algorithm type.
*
* @return type
*/
String
getType
();
/**
* Get properties.
*
* @return properties of algorithm
*/
Properties
getProperties
();
/**
* Set properties.
*
* @param properties properties of algorithm
*/
void
setProperties
(
Properties
properties
);
}
loit-build-component/loit-keygen-leaf-zk/src/main/java/com/loit/component/keygen/leaf/core/spi/TypeBasedSPIConfiguration.java
0 → 100644
浏览文件 @
c690f89d
package
com
.
loit
.
component
.
keygen
.
leaf
.
core
.
spi
;
import
com.google.common.base.Preconditions
;
import
com.google.common.base.Strings
;
import
lombok.Getter
;
import
java.util.Properties
;
/**
* Type based SPI configuration.
*
* @author zhangliang
*/
@Getter
public
abstract
class
TypeBasedSPIConfiguration
{
private
final
String
type
;
private
final
Properties
properties
;
public
TypeBasedSPIConfiguration
(
final
String
type
)
{
this
(
type
,
null
);
}
public
TypeBasedSPIConfiguration
(
final
String
type
,
final
Properties
properties
)
{
Preconditions
.
checkArgument
(!
Strings
.
isNullOrEmpty
(
type
),
"Type is required."
);
this
.
type
=
type
;
this
.
properties
=
null
==
properties
?
new
Properties
()
:
properties
;
}
}
loit-build-component/loit-keygen-leaf-zk/src/main/java/com/loit/component/keygen/leaf/core/spi/TypeBasedSPIServiceLoader.java
0 → 100644
浏览文件 @
c690f89d
package
com
.
loit
.
component
.
keygen
.
leaf
.
core
.
spi
;
import
com.google.common.base.Predicate
;
import
com.google.common.collect.Collections2
;
import
com.loit.component.keygen.leaf.core.NewInstanceServiceLoader
;
import
com.loit.component.keygen.leaf.core.exception.LeafConfigurationException
;
import
lombok.RequiredArgsConstructor
;
import
java.util.Collection
;
import
java.util.Properties
;
/**
* Type based SPI service loader.
*
* @param <T> type of algorithm class
*/
@RequiredArgsConstructor
public
abstract
class
TypeBasedSPIServiceLoader
<
T
extends
TypeBasedSPI
>
{
private
final
Class
<
T
>
classType
;
/**
* Create new instance for type based SPI.
*
* @param type SPI type
* @param props SPI properties
* @return SPI instance
*/
public
final
T
newService
(
final
String
type
,
final
Properties
props
)
{
Collection
<
T
>
typeBasedServices
=
loadTypeBasedServices
(
type
);
if
(
typeBasedServices
.
isEmpty
())
{
throw
new
LeafConfigurationException
(
"Invalid `%s` SPI type `%s`."
,
classType
.
getName
(),
type
);
}
T
result
=
typeBasedServices
.
iterator
().
next
();
result
.
setProperties
(
props
);
return
result
;
}
/**
* Create new service by default SPI type.
*
* @return type based SPI instance
*/
public
final
T
newService
()
{
T
result
=
loadFirstTypeBasedService
();
result
.
setProperties
(
new
Properties
());
return
result
;
}
private
Collection
<
T
>
loadTypeBasedServices
(
final
String
type
)
{
return
Collections2
.
filter
(
NewInstanceServiceLoader
.
newServiceInstances
(
classType
),
new
Predicate
<
T
>()
{
@Override
public
boolean
apply
(
final
T
input
)
{
return
type
.
equalsIgnoreCase
(
input
.
getType
());
}
});
}
private
T
loadFirstTypeBasedService
()
{
Collection
<
T
>
instances
=
NewInstanceServiceLoader
.
newServiceInstances
(
classType
);
if
(
instances
.
isEmpty
())
{
throw
new
LeafConfigurationException
(
"Invalid `%s` SPI, no implementation class load from SPI."
,
classType
.
getName
());
}
return
instances
.
iterator
().
next
();
}
}
loit-build-component/loit-keygen-leaf-zk/src/main/java/com/loit/component/keygen/leaf/keygen/LeafKeyGenerator.java
0 → 100644
浏览文件 @
c690f89d
package
com
.
loit
.
component
.
keygen
.
leaf
.
keygen
;
import
com.loit.component.keygen.leaf.core.spi.TypeBasedSPI
;
/**
* Key generator.
*
*/
public
interface
LeafKeyGenerator
extends
TypeBasedSPI
{
/**
* Generate key.
*
* @return generated key
*/
Comparable
<?>
generateKey
();
}
loit-build-component/loit-keygen-leaf-zk/src/main/java/com/loit/component/keygen/leaf/package-info.java
0 → 100644
浏览文件 @
c690f89d
package
com
.
loit
.
component
.
keygen
.
leaf
;
\ No newline at end of file
loit-build-component/loit-keygen-leaf-zk/src/main/java/com/loit/component/keygen/leaf/zk/CuratorZookeeperExceptionHandler.java
0 → 100644
浏览文件 @
c690f89d
package
com
.
loit
.
component
.
keygen
.
leaf
.
zk
;
import
com.loit.component.keygen.leaf.core.exception.RegistryCenterException
;
import
lombok.AccessLevel
;
import
lombok.NoArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.zookeeper.KeeperException.ConnectionLossException
;
import
org.apache.zookeeper.KeeperException.NoNodeException
;
import
org.apache.zookeeper.KeeperException.NodeExistsException
;
/**
* Curator zookeeper exception handler.
*
* @author zhangliang
*/
@NoArgsConstructor
(
access
=
AccessLevel
.
PRIVATE
)
@Slf4j
public
final
class
CuratorZookeeperExceptionHandler
{
/**
* Handle exception.
*
* <p>Ignore interrupt and connection invalid exception.</p>
*
* @param cause to be handled exception
*/
public
static
void
handleException
(
final
Exception
cause
)
{
if
(
null
==
cause
)
{
return
;
}
if
(
isIgnoredException
(
cause
)
||
null
!=
cause
.
getCause
()
&&
isIgnoredException
(
cause
.
getCause
()))
{
log
.
debug
(
"Ignored exception for: {}"
,
cause
.
getMessage
());
}
else
if
(
cause
instanceof
InterruptedException
)
{
Thread
.
currentThread
().
interrupt
();
}
else
{
throw
new
RegistryCenterException
(
cause
);
}
}
private
static
boolean
isIgnoredException
(
final
Throwable
cause
)
{
return
cause
instanceof
ConnectionLossException
||
cause
instanceof
NoNodeException
||
cause
instanceof
NodeExistsException
;
}
}
loit-build-component/loit-keygen-leaf-zk/src/main/java/com/loit/component/keygen/leaf/zk/CuratorZookeeperRegistryCenter.java
0 → 100644
浏览文件 @
c690f89d
package
com
.
loit
.
component
.
keygen
.
leaf
.
zk
;
import
com.google.common.base.Charsets
;
import
com.google.common.base.Strings
;
import
com.loit.component.keygen.leaf.core.listener.DataChangedEvent
;
import
com.loit.component.keygen.leaf.core.listener.DataChangedEvent.ChangedType
;
import
com.loit.component.keygen.leaf.core.listener.DataChangedEventListener
;
import
com.loit.component.keygen.leaf.core.reg.RegistryCenter
;
import
com.loit.component.keygen.leaf.core.reg.RegistryCenterConfiguration
;
import
lombok.Getter
;
import
lombok.Setter
;
import
lombok.SneakyThrows
;
import
org.apache.curator.framework.CuratorFramework
;
import
org.apache.curator.framework.CuratorFrameworkFactory
;
import
org.apache.curator.framework.api.ACLProvider
;
import
org.apache.curator.framework.recipes.cache.ChildData
;
import
org.apache.curator.framework.recipes.cache.TreeCache
;
import
org.apache.curator.framework.recipes.cache.TreeCacheEvent
;
import
org.apache.curator.framework.recipes.cache.TreeCacheListener
;
import
org.apache.curator.framework.recipes.locks.InterProcessMutex
;
import
org.apache.curator.retry.ExponentialBackoffRetry
;
import
org.apache.curator.utils.CloseableUtils
;
import
org.apache.zookeeper.CreateMode
;
import
org.apache.zookeeper.KeeperException.OperationTimeoutException
;
import
org.apache.zookeeper.ZooDefs
;
import
org.apache.zookeeper.data.ACL
;
import
java.io.UnsupportedEncodingException
;
import
java.util.*
;
import
java.util.Map.Entry
;
import
java.util.concurrent.TimeUnit
;
/**
* Registry center for zookeeper with curator.
*
* @author zhangliang
*/
public
final
class
CuratorZookeeperRegistryCenter
implements
RegistryCenter
{
private
final
Map
<
String
,
TreeCache
>
caches
=
new
HashMap
<>();
private
CuratorFramework
client
;
private
InterProcessMutex
leafLock
;
@Getter
@Setter
private
Properties
properties
=
new
Properties
();
@Override
public
void
init
(
final
RegistryCenterConfiguration
config
)
{
client
=
buildCuratorClient
(
config
);
initCuratorClient
(
config
);
}
private
CuratorFramework
buildCuratorClient
(
final
RegistryCenterConfiguration
config
)
{
CuratorFrameworkFactory
.
Builder
builder
=
CuratorFrameworkFactory
.
builder
()
.
connectString
(
config
.
getServerLists
())
.
retryPolicy
(
new
ExponentialBackoffRetry
(
config
.
getRetryIntervalMilliseconds
(),
config
.
getMaxRetries
(),
config
.
getRetryIntervalMilliseconds
()
*
config
.
getMaxRetries
()))
.
namespace
(
config
.
getNamespace
());
if
(
0
!=
config
.
getTimeToLiveSeconds
())
{
builder
.
sessionTimeoutMs
(
config
.
getTimeToLiveSeconds
()
*
1000
);
}
if
(
0
!=
config
.
getOperationTimeoutMilliseconds
())
{
builder
.
connectionTimeoutMs
(
config
.
getOperationTimeoutMilliseconds
());
}
if
(!
Strings
.
isNullOrEmpty
(
config
.
getDigest
()))
{
builder
.
authorization
(
"digest"
,
config
.
getDigest
().
getBytes
(
Charsets
.
UTF_8
))
.
aclProvider
(
new
ACLProvider
()
{
@Override
public
List
<
ACL
>
getDefaultAcl
()
{
return
ZooDefs
.
Ids
.
CREATOR_ALL_ACL
;
}
@Override
public
List
<
ACL
>
getAclForPath
(
final
String
path
)
{
return
ZooDefs
.
Ids
.
CREATOR_ALL_ACL
;
}
});
}
return
builder
.
build
();
}
private
void
initCuratorClient
(
final
RegistryCenterConfiguration
config
)
{
client
.
start
();
try
{
if
(!
client
.
blockUntilConnected
(
config
.
getRetryIntervalMilliseconds
()
*
config
.
getMaxRetries
(),
TimeUnit
.
MILLISECONDS
))
{
client
.
close
();
throw
new
OperationTimeoutException
();
}
}
catch
(
final
InterruptedException
|
OperationTimeoutException
ex
)
{
CuratorZookeeperExceptionHandler
.
handleException
(
ex
);
}
}
@Override
public
String
get
(
final
String
key
)
{
TreeCache
cache
=
findTreeCache
(
key
);
if
(
null
==
cache
)
{
return
getDirectly
(
key
);
}
ChildData
resultInCache
=
cache
.
getCurrentData
(
key
);
if
(
null
!=
resultInCache
)
{
return
null
==
resultInCache
.
getData
()
?
null
:
new
String
(
resultInCache
.
getData
(),
Charsets
.
UTF_8
);
}
return
getDirectly
(
key
);
}
private
TreeCache
findTreeCache
(
final
String
key
)
{
for
(
Entry
<
String
,
TreeCache
>
entry
:
caches
.
entrySet
())
{
if
(
key
.
startsWith
(
entry
.
getKey
()))
{
return
entry
.
getValue
();
}
}
return
null
;
}
@Override
public
String
getDirectly
(
final
String
key
)
{
try
{
return
new
String
(
client
.
getData
().
forPath
(
key
),
Charsets
.
UTF_8
);
// CHECKSTYLE:OFF
}
catch
(
final
Exception
ex
)
{
// CHECKSTYLE:ON
CuratorZookeeperExceptionHandler
.
handleException
(
ex
);
return
null
;
}
}
@Override
public
boolean
isExisted
(
final
String
key
)
{
try
{
return
null
!=
client
.
checkExists
().
forPath
(
key
);
// CHECKSTYLE:OFF
}
catch
(
final
Exception
ex
)
{
// CHECKSTYLE:ON
CuratorZookeeperExceptionHandler
.
handleException
(
ex
);
return
false
;
}
}
@Override
public
List
<
String
>
getChildrenKeys
(
final
String
key
)
{
try
{
List
<
String
>
result
=
client
.
getChildren
().
forPath
(
key
);
Collections
.
sort
(
result
,
new
Comparator
<
String
>()
{
@Override
public
int
compare
(
final
String
o1
,
final
String
o2
)
{
return
o2
.
compareTo
(
o1
);
}
});
return
result
;
// CHECKSTYLE:OFF
}
catch
(
final
Exception
ex
)
{
// CHECKSTYLE:ON
CuratorZookeeperExceptionHandler
.
handleException
(
ex
);
return
Collections
.
emptyList
();
}
}
@Override
public
void
persist
(
final
String
key
,
final
String
value
)
{
try
{
if
(!
isExisted
(
key
))
{
client
.
create
().
creatingParentsIfNeeded
().
withMode
(
CreateMode
.
PERSISTENT
).
forPath
(
key
,
value
.
getBytes
(
Charsets
.
UTF_8
));
}
else
{
update
(
key
,
value
);
}
// CHECKSTYLE:OFF
}
catch
(
final
Exception
ex
)
{
// CHECKSTYLE:ON
CuratorZookeeperExceptionHandler
.
handleException
(
ex
);
}
}
@Override
public
void
update
(
final
String
key
,
final
String
value
)
{
try
{
client
.
inTransaction
().
check
().
forPath
(
key
).
and
().
setData
().
forPath
(
key
,
value
.
getBytes
(
Charsets
.
UTF_8
)).
and
().
commit
();
// CHECKSTYLE:OFF
}
catch
(
final
Exception
ex
)
{
// CHECKSTYLE:ON
CuratorZookeeperExceptionHandler
.
handleException
(
ex
);
}
}
@Override
public
void
persistEphemeral
(
final
String
key
,
final
String
value
)
{
try
{
if
(
isExisted
(
key
))
{
client
.
delete
().
deletingChildrenIfNeeded
().
forPath
(
key
);
}
client
.
create
().
creatingParentsIfNeeded
().
withMode
(
CreateMode
.
EPHEMERAL
).
forPath
(
key
,
value
.
getBytes
(
Charsets
.
UTF_8
));
// CHECKSTYLE:OFF
}
catch
(
final
Exception
ex
)
{
// CHECKSTYLE:ON
CuratorZookeeperExceptionHandler
.
handleException
(
ex
);
}
}
@Override
public
void
watch
(
final
String
key
,
final
DataChangedEventListener
dataChangedEventListener
)
{
final
String
path
=
key
+
"/"
;
if
(!
caches
.
containsKey
(
path
))
{
addCacheData
(
key
);
}
TreeCache
cache
=
caches
.
get
(
path
);
cache
.
getListenable
().
addListener
(
new
TreeCacheListener
()
{
@Override
public
void
childEvent
(
final
CuratorFramework
client
,
final
TreeCacheEvent
event
)
throws
UnsupportedEncodingException
{
ChildData
data
=
event
.
getData
();
if
(
null
==
data
||
null
==
data
.
getPath
())
{
return
;
}
ChangedType
changedType
=
getChangedType
(
event
);
if
(
ChangedType
.
IGNORED
!=
changedType
)
{
dataChangedEventListener
.
onChange
(
new
DataChangedEvent
(
data
.
getPath
(),
null
==
data
.
getData
()
?
null
:
new
String
(
data
.
getData
(),
"UTF-8"
),
changedType
));
}
}
});
}
private
ChangedType
getChangedType
(
final
TreeCacheEvent
event
)
{
switch
(
event
.
getType
())
{
case
NODE_UPDATED:
return
DataChangedEvent
.
ChangedType
.
UPDATED
;
case
NODE_REMOVED:
return
DataChangedEvent
.
ChangedType
.
DELETED
;
default
:
return
DataChangedEvent
.
ChangedType
.
IGNORED
;
}
}
private
void
addCacheData
(
final
String
cachePath
)
{
TreeCache
cache
=
new
TreeCache
(
client
,
cachePath
);
try
{
cache
.
start
();
// CHECKSTYLE:OFF
}
catch
(
final
Exception
ex
)
{
// CHECKSTYLE:ON
CuratorZookeeperExceptionHandler
.
handleException
(
ex
);
}
caches
.
put
(
cachePath
+
"/"
,
cache
);
}
@Override
public
void
close
()
{
for
(
Entry
<
String
,
TreeCache
>
each
:
caches
.
entrySet
())
{
each
.
getValue
().
close
();
}
waitForCacheClose
();
CloseableUtils
.
closeQuietly
(
client
);
}
/* TODO 等待500ms, cache先关闭再关闭client, 否则会抛异常
* 因为异步处理, 可能会导致client先关闭而cache还未关闭结束.
* 等待Curator新版本解决这个bug.
* BUG地址:https://issues.apache.org/jira/browse/CURATOR-157
*/
private
void
waitForCacheClose
()
{
try
{
Thread
.
sleep
(
500L
);
}
catch
(
final
InterruptedException
ex
)
{
Thread
.
currentThread
().
interrupt
();
}
}
@Override
public
String
getType
()
{
return
"zookeeper"
;
}
@Override
public
void
initLock
(
final
String
key
)
{
leafLock
=
new
InterProcessMutex
(
client
,
key
);
}
@Override
@SneakyThrows
public
boolean
tryLock
()
{
return
leafLock
.
acquire
(
5
,
TimeUnit
.
SECONDS
);
}
@Override
@SneakyThrows
public
void
tryRelease
()
{
leafLock
.
release
();
}
}
loit-build-component/loit-keygen-leaf-zk/src/main/resources/META-INF/services/com.loit.component.keygen.leaf.core.reg.RegistryCenter
0 → 100644
浏览文件 @
c690f89d
com.loit.component.keygen.leaf.zk.CuratorZookeeperRegistryCenter
loit-build-component/loit-keygen-leaf-zk/src/test/java/com/loit/component/keygen/leaf/LeafSegmentLeafKeyGeneratorTest.java
0 → 100644
浏览文件 @
c690f89d
package
com
.
loit
.
component
.
keygen
.
leaf
;
import
org.junit.FixMethodOrder
;
import
org.junit.Test
;
import
org.junit.runners.MethodSorters
;
import
java.util.*
;
import
java.util.concurrent.Callable
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
import
static
org
.
hamcrest
.
CoreMatchers
.
is
;
import
static
org
.
junit
.
Assert
.
assertThat
;
@FixMethodOrder
(
value
=
MethodSorters
.
NAME_ASCENDING
)
public
final
class
LeafSegmentLeafKeyGeneratorTest
{
private
final
LeafSegmentLeafKeyGenerator
leafSegmentKeyGenerator
=
new
LeafSegmentLeafKeyGenerator
();
@Test
public
void
assertGetProperties
()
{
assertThat
(
leafSegmentKeyGenerator
.
getProperties
().
entrySet
().
size
(),
is
(
0
));
}
@Test
public
void
assertSetProperties
()
{
Properties
properties
=
new
Properties
();
properties
.
setProperty
(
"key1"
,
"value1"
);
leafSegmentKeyGenerator
.
setProperties
(
properties
);
assertThat
(
leafSegmentKeyGenerator
.
getProperties
().
get
(
"key1"
),
is
((
Object
)
"value1"
));
}
@Test
public
void
assertGenerateKeyWithSingleThread
()
{
Properties
properties
=
new
Properties
();
properties
.
setProperty
(
"serverList"
,
"127.0.0.1:2181"
);
properties
.
setProperty
(
"initialValue"
,
"100001"
);
properties
.
setProperty
(
"step"
,
"5"
);
properties
.
setProperty
(
"leafKey"
,
"test_table_1"
);
properties
.
setProperty
(
"registryCenterType"
,
"zookeeper"
);
leafSegmentKeyGenerator
.
setProperties
(
properties
);
List
<
Comparable
<?>>
expected
=
Arrays
.<
Comparable
<?>>
asList
(
100001L
,
100002L
,
100003L
,
100004L
,
100005L
,
100006L
,
100007L
,
100008L
,
100009L
,
100010L
);
List
<
Comparable
<?>>
actual
=
new
ArrayList
<>();
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
actual
.
add
(
leafSegmentKeyGenerator
.
generateKey
());
}
assertThat
(
actual
,
is
(
expected
));
}
@Test
public
void
assertGenerateKeyWithFirstSpecialStep
()
{
Properties
properties
=
new
Properties
();
properties
.
setProperty
(
"serverList"
,
"127.0.0.1:2181"
);
properties
.
setProperty
(
"initialValue"
,
"100001"
);
properties
.
setProperty
(
"step"
,
"3"
);
properties
.
setProperty
(
"leafKey"
,
"test_table_6"
);
properties
.
setProperty
(
"registryCenterType"
,
"ThirdTestRegistryCenter"
);
leafSegmentKeyGenerator
.
setProperties
(
properties
);
List
<
Comparable
<?>>
expected
=
Arrays
.<
Comparable
<?>>
asList
(
100001L
,
100002L
,
100003L
,
100004L
,
100005L
,
100006L
,
100007L
,
100008L
,
100009L
,
100010L
);
List
<
Comparable
<?>>
actual
=
new
ArrayList
<>();
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
actual
.
add
(
leafSegmentKeyGenerator
.
generateKey
());
}
assertThat
(
actual
,
is
(
expected
));
}
@Test
public
void
assertGenerateKeyWithSecondSpecialStep
()
{
Properties
properties
=
new
Properties
();
properties
.
setProperty
(
"serverList"
,
"127.0.0.1:2181"
);
properties
.
setProperty
(
"initialValue"
,
"100001"
);
properties
.
setProperty
(
"step"
,
"7"
);
properties
.
setProperty
(
"leafKey"
,
"test_table_7"
);
properties
.
setProperty
(
"registryCenterType"
,
"ThirdTestRegistryCenter"
);
leafSegmentKeyGenerator
.
setProperties
(
properties
);
List
<
Comparable
<?>>
expected
=
Arrays
.<
Comparable
<?>>
asList
(
100001L
,
100002L
,
100003L
,
100004L
,
100005L
,
100006L
,
100007L
,
100008L
,
100009L
,
100010L
);
List
<
Comparable
<?>>
actual
=
new
ArrayList
<>();
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
actual
.
add
(
leafSegmentKeyGenerator
.
generateKey
());
}
assertThat
(
actual
,
is
(
expected
));
}
@Test
public
void
assertGenerateKeyWithMultipleThreads
()
throws
Exception
{
int
threadNumber
=
2
;
ExecutorService
executor
=
Executors
.
newFixedThreadPool
(
threadNumber
);
Properties
properties
=
new
Properties
();
properties
.
setProperty
(
"serverList"
,
"127.0.0.1:2181"
);
properties
.
setProperty
(
"initialValue"
,
"100001"
);
properties
.
setProperty
(
"step"
,
"3"
);
properties
.
setProperty
(
"leafKey"
,
"test_table_2"
);
properties
.
setProperty
(
"registryCenterType"
,
"ThirdTestRegistryCenter"
);
leafSegmentKeyGenerator
.
setProperties
(
properties
);
Set
<
Comparable
<?>>
actual
=
new
HashSet
<>();
int
taskNumber
=
threadNumber
*
2
;
for
(
int
i
=
0
;
i
<
taskNumber
;
i
++)
{
actual
.
add
(
executor
.
submit
(
new
Callable
<
Comparable
<?>>()
{
@Override
public
Comparable
<?>
call
()
{
return
leafSegmentKeyGenerator
.
generateKey
();
}
}).
get
());
}
assertThat
(
actual
.
size
(),
is
(
taskNumber
));
}
@Test
public
void
assertGenerateKeyWithDigest
()
throws
Exception
{
int
threadNumber
=
2
;
ExecutorService
executor
=
Executors
.
newFixedThreadPool
(
threadNumber
);
Properties
properties
=
new
Properties
();
properties
.
setProperty
(
"serverList"
,
"127.0.0.1:2181"
);
properties
.
setProperty
(
"initialValue"
,
"100001"
);
properties
.
setProperty
(
"step"
,
"3"
);
properties
.
setProperty
(
"digest"
,
"name:123456"
);
properties
.
setProperty
(
"leafKey"
,
"test_table_3"
);
properties
.
setProperty
(
"registryCenterType"
,
"ThirdTestRegistryCenter"
);
leafSegmentKeyGenerator
.
setProperties
(
properties
);
Set
<
Comparable
<?>>
actual
=
new
HashSet
<>();
int
taskNumber
=
threadNumber
*
2
;
for
(
int
i
=
0
;
i
<
taskNumber
;
i
++)
{
actual
.
add
(
executor
.
submit
(
new
Callable
<
Comparable
<?>>()
{
@Override
public
Comparable
<?>
call
()
{
return
leafSegmentKeyGenerator
.
generateKey
();
}
}).
get
());
}
assertThat
(
actual
.
size
(),
is
(
taskNumber
));
}
@Test
public
void
assertGenerateKeyWithDefaultStep
()
throws
Exception
{
int
threadNumber
=
2
;
ExecutorService
executor
=
Executors
.
newFixedThreadPool
(
threadNumber
);
Properties
properties
=
new
Properties
();
properties
.
setProperty
(
"serverList"
,
"127.0.0.1:2181"
);
properties
.
setProperty
(
"initialValue"
,
"100001"
);
properties
.
setProperty
(
"leafKey"
,
"test_table_4"
);
properties
.
setProperty
(
"registryCenterType"
,
"ThirdTestRegistryCenter"
);
leafSegmentKeyGenerator
.
setProperties
(
properties
);
Set
<
Comparable
<?>>
actual
=
new
HashSet
<>();
int
taskNumber
=
threadNumber
*
2
;
for
(
int
i
=
0
;
i
<
taskNumber
;
i
++)
{
actual
.
add
(
executor
.
submit
(
new
Callable
<
Comparable
<?>>()
{
@Override
public
Comparable
<?>
call
()
{
return
leafSegmentKeyGenerator
.
generateKey
();
}
}).
get
());
}
assertThat
(
actual
.
size
(),
is
(
taskNumber
));
}
@Test
public
void
assertGenerateKeyWithDefaultInitialValue
()
throws
Exception
{
int
threadNumber
=
2
;
ExecutorService
executor
=
Executors
.
newFixedThreadPool
(
threadNumber
);
Properties
properties
=
new
Properties
();
properties
.
setProperty
(
"serverList"
,
"127.0.0.1:2181"
);
properties
.
setProperty
(
"step"
,
"3"
);
properties
.
setProperty
(
"leafKey"
,
"test_table_5"
);
properties
.
setProperty
(
"registryCenterType"
,
"ThirdTestRegistryCenter"
);
leafSegmentKeyGenerator
.
setProperties
(
properties
);
int
taskNumber
=
threadNumber
*
2
;
Set
<
Comparable
<?>>
actual
=
new
HashSet
<>();
for
(
int
i
=
0
;
i
<
taskNumber
;
i
++)
{
actual
.
add
(
executor
.
submit
(
new
Callable
<
Comparable
<?>>()
{
@Override
public
Comparable
<?>
call
()
{
return
leafSegmentKeyGenerator
.
generateKey
();
}
}).
get
());
}
assertThat
(
actual
.
size
(),
is
(
taskNumber
));
}
@Test
(
expected
=
IllegalArgumentException
.
class
)
public
void
assertSetStepFailureWhenNegative
()
{
Properties
properties
=
new
Properties
();
properties
.
setProperty
(
"serverList"
,
"127.0.0.1:2181"
);
properties
.
setProperty
(
"step"
,
String
.
valueOf
(-
1L
));
properties
.
setProperty
(
"initialValue"
,
"100001"
);
properties
.
setProperty
(
"leafKey"
,
"test_table_9"
);
properties
.
setProperty
(
"registryCenterType"
,
"ThirdTestRegistryCenter"
);
leafSegmentKeyGenerator
.
setProperties
(
properties
);
leafSegmentKeyGenerator
.
generateKey
();
}
@Test
(
expected
=
IllegalArgumentException
.
class
)
public
void
assertSetStepFailureWhenZero
()
{
Properties
properties
=
new
Properties
();
properties
.
setProperty
(
"serverList"
,
"127.0.0.1:2181"
);
properties
.
setProperty
(
"step"
,
String
.
valueOf
(
0L
));
properties
.
setProperty
(
"initialValue"
,
"100001"
);
properties
.
setProperty
(
"leafKey"
,
"test_table_10"
);
properties
.
setProperty
(
"registryCenterType"
,
"ThirdTestRegistryCenter"
);
leafSegmentKeyGenerator
.
setProperties
(
properties
);
leafSegmentKeyGenerator
.
generateKey
();
}
@Test
(
expected
=
IllegalArgumentException
.
class
)
public
void
assertSetStepFailureWhenTooMuch
()
{
Properties
properties
=
new
Properties
();
properties
.
setProperty
(
"serverList"
,
"127.0.0.1:2181"
);
properties
.
setProperty
(
"step"
,
String
.
valueOf
(
Long
.
MAX_VALUE
));
properties
.
setProperty
(
"initialValue"
,
"100001"
);
properties
.
setProperty
(
"leafKey"
,
"test_table_11"
);
properties
.
setProperty
(
"registryCenterType"
,
"ThirdTestRegistryCenter"
);
leafSegmentKeyGenerator
.
setProperties
(
properties
);
leafSegmentKeyGenerator
.
generateKey
();
}
@Test
(
expected
=
IllegalArgumentException
.
class
)
public
void
assertSetInitialValueFailureWhenNegative
()
{
Properties
properties
=
new
Properties
();
properties
.
setProperty
(
"serverList"
,
"127.0.0.1:2181"
);
properties
.
setProperty
(
"step"
,
"3"
);
properties
.
setProperty
(
"initialValue"
,
String
.
valueOf
(-
1L
));
properties
.
setProperty
(
"leafKey"
,
"test_table_12"
);
properties
.
setProperty
(
"registryCenterType"
,
"ThirdTestRegistryCenter"
);
leafSegmentKeyGenerator
.
setProperties
(
properties
);
leafSegmentKeyGenerator
.
generateKey
();
}
@Test
(
expected
=
IllegalArgumentException
.
class
)
public
void
assertSetInitialValueFailureWhenTooMuch
()
{
Properties
properties
=
new
Properties
();
properties
.
setProperty
(
"serverList"
,
"127.0.0.1:2181"
);
properties
.
setProperty
(
"step"
,
"3"
);
properties
.
setProperty
(
"initialValue"
,
String
.
valueOf
(
Long
.
MAX_VALUE
));
properties
.
setProperty
(
"leafKey"
,
"test_table_13"
);
properties
.
setProperty
(
"registryCenterType"
,
"ThirdTestRegistryCenter"
);
leafSegmentKeyGenerator
.
setProperties
(
properties
);
leafSegmentKeyGenerator
.
generateKey
();
}
@Test
(
expected
=
IllegalArgumentException
.
class
)
public
void
assertSetServerListFailureWhenNull
()
{
Properties
properties
=
new
Properties
();
properties
.
setProperty
(
"step"
,
"3"
);
properties
.
setProperty
(
"initialValue"
,
"100001"
);
properties
.
setProperty
(
"leafKey"
,
"test_table_14"
);
properties
.
setProperty
(
"registryCenterType"
,
"ThirdTestRegistryCenter"
);
leafSegmentKeyGenerator
.
setProperties
(
properties
);
leafSegmentKeyGenerator
.
generateKey
();
}
@Test
(
expected
=
IllegalArgumentException
.
class
)
public
void
assertSetServerListFailureWhenArgumentEmpty
()
{
Properties
properties
=
new
Properties
();
properties
.
setProperty
(
"serverList"
,
""
);
properties
.
setProperty
(
"step"
,
"3"
);
properties
.
setProperty
(
"initialValue"
,
"100001"
);
properties
.
setProperty
(
"leafKey"
,
"test_table_15"
);
properties
.
setProperty
(
"registryCenterType"
,
"ThirdTestRegistryCenter"
);
leafSegmentKeyGenerator
.
setProperties
(
properties
);
leafSegmentKeyGenerator
.
generateKey
();
}
@Test
(
expected
=
IllegalArgumentException
.
class
)
public
void
assertSetLeafKeyFailureWhenArgumentIllegal
()
{
Properties
properties
=
new
Properties
();
properties
.
setProperty
(
"serverList"
,
"127.0.0.1:2181"
);
properties
.
setProperty
(
"step"
,
"3"
);
properties
.
setProperty
(
"initialValue"
,
"100001"
);
properties
.
setProperty
(
"leafKey"
,
"/test_table_16"
);
properties
.
setProperty
(
"registryCenterType"
,
"ThirdTestRegistryCenter"
);
leafSegmentKeyGenerator
.
setProperties
(
properties
);
leafSegmentKeyGenerator
.
generateKey
();
}
@Test
(
expected
=
IllegalArgumentException
.
class
)
public
void
assertSetLeafKeyFailureWhenArgumentEmpty
()
{
Properties
properties
=
new
Properties
();
properties
.
setProperty
(
"serverList"
,
"127.0.0.1:2181"
);
properties
.
setProperty
(
"step"
,
"3"
);
properties
.
setProperty
(
"initialValue"
,
"100001"
);
properties
.
setProperty
(
"leafKey"
,
""
);
properties
.
setProperty
(
"registryCenterType"
,
"ThirdTestRegistryCenter"
);
leafSegmentKeyGenerator
.
setProperties
(
properties
);
leafSegmentKeyGenerator
.
generateKey
();
}
@Test
(
expected
=
IllegalArgumentException
.
class
)
public
void
assertSetLeafKeyFailureWhenNull
()
{
Properties
properties
=
new
Properties
();
properties
.
setProperty
(
"serverList"
,
"127.0.0.1:2181"
);
properties
.
setProperty
(
"step"
,
"3"
);
properties
.
setProperty
(
"initialValue"
,
"100001"
);
properties
.
setProperty
(
"registryCenterType"
,
"ThirdTestRegistryCenter"
);
leafSegmentKeyGenerator
.
setProperties
(
properties
);
leafSegmentKeyGenerator
.
generateKey
();
}
@Test
(
expected
=
IllegalArgumentException
.
class
)
public
void
assertSetRegistryCenterTypeFailureWhenWrongType
()
{
Properties
properties
=
new
Properties
();
properties
.
setProperty
(
"serverList"
,
"127.0.0.1:2181"
);
properties
.
setProperty
(
"step"
,
"3"
);
properties
.
setProperty
(
"initialValue"
,
"100001"
);
properties
.
setProperty
(
"leafKey"
,
"/test_table_17"
);
properties
.
setProperty
(
"registryCenterType"
,
"ThirdTestRegistryCenter"
);
leafSegmentKeyGenerator
.
setProperties
(
properties
);
leafSegmentKeyGenerator
.
generateKey
();
}
}
loit-build-component/loit-keygen-leaf-zk/src/test/java/com/loit/component/keygen/leaf/package-info.java
0 → 100644
浏览文件 @
c690f89d
package
com
.
loit
.
component
.
keygen
.
leaf
;
\ No newline at end of file
loit-build-component/loit-keygen-leaf-zk/src/test/java/com/loit/component/keygen/leaf/zk/CuratorZookeeperRegistryCenterTest.java
0 → 100644
浏览文件 @
c690f89d
package
com
.
loit
.
component
.
keygen
.
leaf
.
zk
;
import
com.loit.component.keygen.leaf.core.reg.RegistryCenter
;
import
com.loit.component.keygen.leaf.core.reg.RegistryCenterConfiguration
;
import
com.loit.component.keygen.leaf.zk.util.EmbedTestingServer
;
import
org.junit.BeforeClass
;
import
org.junit.Test
;
import
java.util.List
;
import
java.util.Properties
;
import
static
org
.
hamcrest
.
CoreMatchers
.
is
;
import
static
org
.
junit
.
Assert
.
assertThat
;
public
class
CuratorZookeeperRegistryCenterTest
{
private
static
RegistryCenter
curatorZookeeperRegistryCenter
=
new
CuratorZookeeperRegistryCenter
();
@BeforeClass
public
static
void
init
()
{
EmbedTestingServer
.
start
();
RegistryCenterConfiguration
configuration
=
new
RegistryCenterConfiguration
(
curatorZookeeperRegistryCenter
.
getType
(),
new
Properties
());
configuration
.
setServerLists
(
"127.0.0.1:2181"
);
curatorZookeeperRegistryCenter
.
init
(
configuration
);
}
@Test
public
void
assertPersist
()
{
curatorZookeeperRegistryCenter
.
persist
(
"/test"
,
"value1"
);
assertThat
(
curatorZookeeperRegistryCenter
.
get
(
"/test"
),
is
(
"value1"
));
}
@Test
public
void
assertUpdate
()
{
curatorZookeeperRegistryCenter
.
persist
(
"/test"
,
"value2"
);
assertThat
(
curatorZookeeperRegistryCenter
.
get
(
"/test"
),
is
(
"value2"
));
}
@Test
public
void
assertPersistEphemeral
()
{
curatorZookeeperRegistryCenter
.
persist
(
"/test/ephemeral"
,
"value3"
);
assertThat
(
curatorZookeeperRegistryCenter
.
get
(
"/test/ephemeral"
),
is
(
"value3"
));
}
@Test
public
void
assertGetDirectly
()
{
curatorZookeeperRegistryCenter
.
persist
(
"/test"
,
"value4"
);
assertThat
(
curatorZookeeperRegistryCenter
.
getDirectly
(
"/test"
),
is
(
"value4"
));
}
@Test
public
void
assertIsExisted
()
{
curatorZookeeperRegistryCenter
.
persist
(
"/test/existed"
,
"value5"
);
assertThat
(
curatorZookeeperRegistryCenter
.
isExisted
(
"/test/existed"
),
is
(
true
));
}
@Test
public
void
assertGetChildrenKeys
()
{
curatorZookeeperRegistryCenter
.
persist
(
"/test/children/1"
,
"value11"
);
curatorZookeeperRegistryCenter
.
persist
(
"/test/children/2"
,
"value12"
);
curatorZookeeperRegistryCenter
.
persist
(
"/test/children/3"
,
"value13"
);
List
<
String
>
childrenKeys
=
curatorZookeeperRegistryCenter
.
getChildrenKeys
(
"/test/children"
);
assertThat
(
childrenKeys
.
size
(),
is
(
3
));
}
@Test
public
void
assertLock
()
{
curatorZookeeperRegistryCenter
.
initLock
(
"/test/lock1"
);
assertThat
(
curatorZookeeperRegistryCenter
.
tryLock
(),
is
(
true
));
}
@Test
public
void
assertRelease
()
{
curatorZookeeperRegistryCenter
.
initLock
(
"/test/lock2"
);
curatorZookeeperRegistryCenter
.
tryLock
();
curatorZookeeperRegistryCenter
.
tryRelease
();
}
@Test
(
expected
=
IllegalMonitorStateException
.
class
)
public
void
assertReleaseWithoutLock
()
{
curatorZookeeperRegistryCenter
.
initLock
(
"/test/lock3"
);
curatorZookeeperRegistryCenter
.
tryRelease
();
}
}
loit-build-component/loit-keygen-leaf-zk/src/test/java/com/loit/component/keygen/leaf/zk/ThirdTestRegistryCenter.java
0 → 100644
浏览文件 @
c690f89d
package
com
.
loit
.
component
.
keygen
.
leaf
.
zk
;
import
com.loit.component.keygen.leaf.core.listener.DataChangedEventListener
;
import
com.loit.component.keygen.leaf.core.reg.RegistryCenter
;
import
com.loit.component.keygen.leaf.core.reg.RegistryCenterConfiguration
;
import
lombok.Getter
;
import
lombok.Setter
;
import
java.util.*
;
import
java.util.concurrent.locks.ReentrantLock
;
public
final
class
ThirdTestRegistryCenter
implements
RegistryCenter
{
private
final
Map
<
String
,
String
>
keys
=
new
HashMap
<>();
@Getter
@Setter
private
Properties
properties
=
new
Properties
();
private
ReentrantLock
lock
=
new
ReentrantLock
();
@Override
public
void
init
(
final
RegistryCenterConfiguration
config
)
{
}
@Override
public
String
get
(
final
String
key
)
{
return
""
;
}
@Override
public
String
getDirectly
(
final
String
key
)
{
return
keys
.
get
(
key
);
}
@Override
public
boolean
isExisted
(
final
String
key
)
{
return
keys
.
containsKey
(
key
);
}
@Override
public
List
<
String
>
getChildrenKeys
(
final
String
key
)
{
return
Collections
.
emptyList
();
}
@Override
public
void
persist
(
final
String
key
,
final
String
value
)
{
keys
.
put
(
key
,
value
);
}
@Override
public
void
update
(
final
String
key
,
final
String
value
)
{
keys
.
put
(
key
,
value
);
}
@Override
public
void
persistEphemeral
(
final
String
key
,
final
String
value
)
{
}
@Override
public
void
watch
(
final
String
key
,
final
DataChangedEventListener
dataChangedEventListener
)
{
}
@Override
public
void
close
()
{
}
@Override
public
String
getType
()
{
return
"ThirdTestRegistryCenter"
;
}
@Override
public
void
initLock
(
final
String
key
)
{
lock
=
new
ReentrantLock
();
}
@Override
public
boolean
tryLock
()
{
return
lock
.
tryLock
();
}
@Override
public
void
tryRelease
()
{
lock
.
unlock
();
}
}
loit-build-component/loit-keygen-leaf-zk/src/test/java/com/loit/component/keygen/leaf/zk/util/EmbedTestingServer.java
0 → 100644
浏览文件 @
c690f89d
package
com
.
loit
.
component
.
keygen
.
leaf
.
zk
.
util
;
import
lombok.AccessLevel
;
import
lombok.NoArgsConstructor
;
import
org.apache.curator.test.TestingServer
;
import
org.apache.zookeeper.KeeperException
;
import
java.io.File
;
import
java.io.IOException
;
@NoArgsConstructor
(
access
=
AccessLevel
.
PRIVATE
)
public
final
class
EmbedTestingServer
{
private
static
final
int
PORT
=
3181
;
private
static
volatile
TestingServer
testingServer
;
/**
* Start embed zookeeper server.
*/
public
static
void
start
()
{
if
(
null
!=
testingServer
)
{
return
;
}
try
{
testingServer
=
new
TestingServer
(
PORT
,
new
File
(
String
.
format
(
"target/test_zk_data/%s/"
,
System
.
nanoTime
())));
// CHECKSTYLE:OFF
}
catch
(
final
Exception
ex
)
{
// CHECKSTYLE:ON
if
(!
isIgnoredException
(
ex
))
{
throw
new
RuntimeException
(
ex
);
}
}
finally
{
Runtime
.
getRuntime
().
addShutdownHook
(
new
Thread
()
{
@Override
public
void
run
()
{
try
{
testingServer
.
close
();
}
catch
(
final
IOException
ignored
)
{
}
}
});
}
}
private
static
boolean
isIgnoredException
(
final
Throwable
cause
)
{
return
cause
instanceof
KeeperException
.
ConnectionLossException
||
cause
instanceof
KeeperException
.
NoNodeException
||
cause
instanceof
KeeperException
.
NodeExistsException
;
}
}
loit-build-component/pom.xml
浏览文件 @
c690f89d
...
...
@@ -18,6 +18,7 @@
<module>
loit-seata-mybatis-mysql-suport
</module>
<module>
loit-component-jetcache-client
</module>
<module>
sharding-keygen-leaf
</module>
<module>
loit-keygen-leaf-zk
</module>
</modules>
</project>
\ No newline at end of file
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论