Skip to content

Commit

Permalink
- add the tool class RedisKeys to support the hashtag of Redis Cl…
Browse files Browse the repository at this point in the history
…uster mode.

- when using Redis cluster mode, it supports automatic conversion of `namespace` to `hashtag`.
- support for parameter defensive check
  • Loading branch information
Ahoo-Wang committed Jul 21, 2021
1 parent 29d340f commit 6d18e2d
Show file tree
Hide file tree
Showing 23 changed files with 261 additions and 103 deletions.
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ between process cache and Redis.
> Kotlin DSL
``` kotlin
val coskyVersion = "1.2.5";
val coskyVersion = "1.2.7";
implementation("me.ahoo.cosky:spring-cloud-starter-cosky-config:${coskyVersion}")
implementation("me.ahoo.cosky:spring-cloud-starter-cosky-discovery:${coskyVersion}")
implementation("org.springframework.cloud:spring-cloud-starter-loadbalancer:3.0.3")
Expand All @@ -50,7 +50,7 @@ between process cache and Redis.
<modelVersion>4.0.0</modelVersion>
<artifactId>demo</artifactId>
<properties>
<cosky.version>1.2.5</cosky.version>
<cosky.version>1.2.7</cosky.version>
</properties>

<dependencies>
Expand Down Expand Up @@ -99,21 +99,21 @@ logging:
#### Option 1:Download the executable file
> Download [cosky-rest-api-server](https://github.com/Ahoo-Wang/cosky/releases/download/1.2.5/cosky-rest-api-1.2.5.tar)
> Download [cosky-rest-api-server](https://github.com/Ahoo-Wang/cosky/releases/download/1.2.7/cosky-rest-api-1.2.7.tar)
> tar *cosky-rest-api-1.2.5.tar*
> tar *cosky-rest-api-1.2.7.tar*
```shell
cd cosky-rest-api-1.2.5
# Working directory: cosky-rest-api-1.2.5
cd cosky-rest-api-1.2.7
# Working directory: cosky-rest-api-1.2.7
bin/cosky-rest-api --server.port=8080 --cosky.redis.uri=redis://localhost:6379
```

#### Option 2:Run On Docker

```shell
docker pull ahoowang/cosky-rest-api:1.2.5
docker run --name cosky-rest-api -d -p 8080:8080 --link redis -e COSKY_REDIS_URI=redis://redis:6379 ahoowang/cosky-rest-api:1.2.5
docker pull ahoowang/cosky-rest-api:1.2.7
docker run --name cosky-rest-api -d -p 8080:8080 --link redis -e COSKY_REDIS_URI=redis://redis:6379 ahoowang/cosky-rest-api:1.2.7
```

#### Option 3:Run On Kubernetes
Expand Down Expand Up @@ -141,7 +141,7 @@ spec:
value: standalone
- name: COSKY_REDIS_URI
value: redis://redis-uri:6379
image: ahoowang/cosky-rest-api:1.2.5
image: ahoowang/cosky-rest-api:1.2.7
name: cosky-rest-api
ports:
- containerPort: 8080
Expand Down Expand Up @@ -306,7 +306,7 @@ spec:
``` shell
gradle cosky-config:jmh
# or
java -jar cosky-config/build/libs/cosky-config-1.2.5-jmh.jar -bm thrpt -t 25 -wi 1 -rf json -f 1
java -jar cosky-config/build/libs/cosky-config-1.2.7-jmh.jar -bm thrpt -t 25 -wi 1 -rf json -f 1
```

```
Expand All @@ -321,7 +321,7 @@ RedisConfigServiceBenchmark.setConfig thrpt 140461.112
``` shell
gradle cosky-discovery:jmh
# or
java -jar cosky-discovery/build/libs/cosky-discovery-1.2.5-jmh.jar -bm thrpt -t 25 -wi 1 -rf json -f 1
java -jar cosky-discovery/build/libs/cosky-discovery-1.2.7-jmh.jar -bm thrpt -t 25 -wi 1 -rf json -f 1
```

```
Expand Down
22 changes: 11 additions & 11 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
> Kotlin DSL
``` kotlin
val coskyVersion = "1.2.5";
val coskyVersion = "1.2.7";
implementation("me.ahoo.cosky:spring-cloud-starter-cosky-config:${coskyVersion}")
implementation("me.ahoo.cosky:spring-cloud-starter-cosky-discovery:${coskyVersion}")
implementation("org.springframework.cloud:spring-cloud-starter-loadbalancer:3.0.3")
Expand All @@ -49,7 +49,7 @@
<modelVersion>4.0.0</modelVersion>
<artifactId>demo</artifactId>
<properties>
<cosky.version>1.2.5</cosky.version>
<cosky.version>1.2.7</cosky.version>
</properties>

<dependencies>
Expand Down Expand Up @@ -98,21 +98,21 @@ logging:
#### 方式一:下载可执行文件
> 下载 [rest-api-server](https://github.com/Ahoo-Wang/cosky/releases/download/1.2.5/cosky-rest-api-1.2.5.tar)
> 下载 [rest-api-server](https://github.com/Ahoo-Wang/cosky/releases/download/1.2.7/cosky-rest-api-1.2.7.tar)
> 解压 *cosky-rest-api-1.2.5.tar*
> 解压 *cosky-rest-api-1.2.7.tar*
```shell
cd cosky-rest-api-1.2.5
# 工作目录: cosky-rest-api-1.2.5
cd cosky-rest-api-1.2.7
# 工作目录: cosky-rest-api-1.2.7
bin/cosky-rest-api --server.port=8080 --cosky.redis.uri=redis://localhost:6379
```

#### 方式二:在 Docker 中运行

```shell
docker pull ahoowang/cosky-rest-api:1.2.5
docker run --name cosky-rest-api -d -p 8080:8080 --link redis -e COSKY_REDIS_URI=redis://redis:6379 ahoowang/cosky-rest-api:1.2.5
docker pull ahoowang/cosky-rest-api:1.2.7
docker run --name cosky-rest-api -d -p 8080:8080 --link redis -e COSKY_REDIS_URI=redis://redis:6379 ahoowang/cosky-rest-api:1.2.7
```

#### 方式三:在 Kubernetes 中运行
Expand Down Expand Up @@ -140,7 +140,7 @@ spec:
value: standalone
- name: COSKY_REDIS_URI
value: redis://redis-uri:6379
image: ahoowang/cosky-rest-api:1.2.5
image: ahoowang/cosky-rest-api:1.2.7
name: cosky-rest-api
ports:
- containerPort: 8080
Expand Down Expand Up @@ -306,7 +306,7 @@ spec:
``` shell
gradle cosky-config:jmh
# or
java -jar cosky-config/build/libs/cosky-config-1.2.5-jmh.jar -bm thrpt -t 25 -wi 1 -rf json -f 1
java -jar cosky-config/build/libs/cosky-config-1.2.7-jmh.jar -bm thrpt -t 25 -wi 1 -rf json -f 1
```

```
Expand All @@ -321,7 +321,7 @@ RedisConfigServiceBenchmark.setConfig thrpt 140461.112
``` shell
gradle cosky-discovery:jmh
# or
java -jar cosky-discovery/build/libs/cosky-discovery-1.2.5-jmh.jar -bm thrpt -t 25 -wi 1 -rf json -f 1
java -jar cosky-discovery/build/libs/cosky-discovery-1.2.7-jmh.jar -bm thrpt -t 25 -wi 1 -rf json -f 1
```

```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@

package me.ahoo.cosky.config.redis;

import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import me.ahoo.cosky.config.*;
import me.ahoo.cosky.core.NamespacedContext;
import me.ahoo.cosky.core.listener.ChannelTopic;
Expand Down Expand Up @@ -61,18 +62,21 @@ public CompletableFuture<Set<String>> getConfigs(String namespace) {

@Override
public CompletableFuture<Config> getConfig(String configId) {
return getConfig(NamespacedContext.GLOBAL.getNamespace(), configId);
return getConfig(NamespacedContext.GLOBAL.getRequiredNamespace(), configId);
}

@Override
public CompletableFuture<Config> getConfig(String namespace, String configId) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(namespace), "namespace can not be empty!");
Preconditions.checkArgument(!Strings.isNullOrEmpty(configId), "configId can not be empty!");

return configMap.computeIfAbsent(NamespacedConfigId.of(namespace, configId), (_configId) -> addListener(namespace, configId).
thenCompose(nil -> delegate.getConfig(namespace, configId)));
}

private CompletableFuture<Void> addListener(String namespace, String configId) {
var topicStr = ConfigKeyGenerator.getConfigKey(namespace, configId);
var configTopic = ChannelTopic.of(topicStr);
String topicStr = ConfigKeyGenerator.getConfigKey(namespace, configId);
ChannelTopic configTopic = ChannelTopic.of(topicStr);
return messageListenable.addListener(configTopic, configListener);
}

Expand Down Expand Up @@ -171,10 +175,10 @@ public void onMessage(Topic topic, String channel, String message) {
log.info("onMessage@ConfigListener - topic:[{}] - channel:[{}] - message:[{}]", topic, channel, message);
}

final var configkey = channel;
var namespacedConfigId = ConfigKeyGenerator.getConfigIdOfKey(configkey);
final String configkey = channel;
NamespacedConfigId namespacedConfigId = ConfigKeyGenerator.getConfigIdOfKey(configkey);
configMap.put(namespacedConfigId, delegate.getConfig(namespacedConfigId.getNamespace(), namespacedConfigId.getConfigId()));
var configChangedListeners = configMapListener.get(namespacedConfigId);
CopyOnWriteArraySet<ConfigChangedListener> configChangedListeners = configMapListener.get(namespacedConfigId);
if (Objects.isNull(configChangedListeners) || configChangedListeners.isEmpty()) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@

import com.google.common.base.Charsets;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.hash.Hashing;
import io.lettuce.core.ScriptOutputType;
import io.lettuce.core.cluster.api.async.RedisClusterAsyncCommands;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import me.ahoo.cosky.config.*;
import me.ahoo.cosky.core.NamespacedContext;

Expand All @@ -43,15 +44,17 @@ public RedisConfigService(RedisClusterAsyncCommands<String, String> redisCommand

@Override
public CompletableFuture<Set<String>> getConfigs() {
return getConfigs(NamespacedContext.GLOBAL.getNamespace());
return getConfigs(NamespacedContext.GLOBAL.getRequiredNamespace());
}

@Override
public CompletableFuture<Set<String>> getConfigs(String namespace) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(namespace), "namespace can not be empty!");

if (log.isDebugEnabled()) {
log.debug("getConfigs @ namespace:[{}].", namespace);
}
var configIdxKey = ConfigKeyGenerator.getConfigIdxKey(namespace);
String configIdxKey = ConfigKeyGenerator.getConfigIdxKey(namespace);
return redisCommands.smembers(configIdxKey).thenApply(configKeySet ->
configKeySet.stream()
.map(configKey -> ConfigKeyGenerator.getConfigIdOfKey(configKey).getConfigId()
Expand All @@ -60,15 +63,18 @@ public CompletableFuture<Set<String>> getConfigs(String namespace) {

@Override
public CompletableFuture<Config> getConfig(String configId) {
return getConfig(NamespacedContext.GLOBAL.getNamespace(), configId);
return getConfig(NamespacedContext.GLOBAL.getRequiredNamespace(), configId);
}

@Override
public CompletableFuture<Config> getConfig(String namespace, String configId) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(namespace), "namespace can not be empty!");
Preconditions.checkArgument(!Strings.isNullOrEmpty(configId), "configId can not be empty!");

if (log.isDebugEnabled()) {
log.debug("getConfig - configId:[{}] @ namespace:[{}].", configId, namespace);
}
var configKey = ConfigKeyGenerator.getConfigKey(namespace, configId);
String configKey = ConfigKeyGenerator.getConfigKey(namespace, configId);
return getAndDecodeConfig(configKey, ConfigCodec::decode);
}

Expand All @@ -79,11 +85,14 @@ public CompletableFuture<Config> getConfig(String namespace, String configId) {
*/
@Override
public CompletableFuture<Boolean> setConfig(String configId, String data) {
return setConfig(NamespacedContext.GLOBAL.getNamespace(), configId, data);
return setConfig(NamespacedContext.GLOBAL.getRequiredNamespace(), configId, data);
}

@Override
public CompletableFuture<Boolean> setConfig(String namespace, String configId, String data) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(namespace), "namespace can not be empty!");
Preconditions.checkArgument(!Strings.isNullOrEmpty(configId), "configId can not be empty!");

String hash = Hashing.sha256().hashString(data, Charsets.UTF_8).toString();
if (log.isInfoEnabled()) {
log.info("setConfig - configId:[{}] - hash:[{}] @ namespace:[{}].", configId, hash, namespace);
Expand All @@ -97,14 +106,18 @@ public CompletableFuture<Boolean> setConfig(String namespace, String configId, S

@Override
public CompletableFuture<Boolean> removeConfig(String configId) {
return removeConfig(NamespacedContext.GLOBAL.getNamespace(), configId);
return removeConfig(NamespacedContext.GLOBAL.getRequiredNamespace(), configId);
}

@Override
public CompletableFuture<Boolean> removeConfig(String namespace, String configId) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(namespace), "namespace can not be empty!");
Preconditions.checkArgument(!Strings.isNullOrEmpty(configId), "configId can not be empty!");

if (log.isInfoEnabled()) {
log.info("removeConfig - configId:[{}] @ namespace:[{}].", configId, namespace);
}

return ConfigRedisScripts.doConfigRemove(redisCommands, sha -> {
String[] keys = {namespace};
String[] values = {configId};
Expand All @@ -114,17 +127,23 @@ public CompletableFuture<Boolean> removeConfig(String namespace, String configId

@Override
public CompletableFuture<Boolean> containsConfig(String namespace, String configId) {
var configKey = ConfigKeyGenerator.getConfigKey(namespace, configId);
Preconditions.checkArgument(!Strings.isNullOrEmpty(namespace), "namespace can not be empty!");
Preconditions.checkArgument(!Strings.isNullOrEmpty(configId), "configId can not be empty!");

String configKey = ConfigKeyGenerator.getConfigKey(namespace, configId);
return redisCommands.exists(configKey).thenApply(count -> count > 0).toCompletableFuture();
}

@Override
public CompletableFuture<Boolean> rollback(String configId, int targetVersion) {
return rollback(NamespacedContext.GLOBAL.getNamespace(), configId, targetVersion);
return rollback(NamespacedContext.GLOBAL.getRequiredNamespace(), configId, targetVersion);
}

@Override
public CompletableFuture<Boolean> rollback(String namespace, String configId, int targetVersion) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(namespace), "namespace can not be empty!");
Preconditions.checkArgument(!Strings.isNullOrEmpty(configId), "configId can not be empty!");

if (log.isInfoEnabled()) {
log.info("rollback - configId:[{}] - targetVersion:[{}] @ namespace:[{}].", configId, targetVersion, namespace);
}
Expand All @@ -139,12 +158,15 @@ public CompletableFuture<Boolean> rollback(String namespace, String configId, in

@Override
public CompletableFuture<List<ConfigVersion>> getConfigVersions(String configId) {
return getConfigVersions(NamespacedContext.GLOBAL.getNamespace(), configId);
return getConfigVersions(NamespacedContext.GLOBAL.getRequiredNamespace(), configId);
}

@Override
public CompletableFuture<List<ConfigVersion>> getConfigVersions(String namespace, String configId) {
var configHistoryIdxKey = ConfigKeyGenerator.getConfigHistoryIdxKey(namespace, configId);
Preconditions.checkArgument(!Strings.isNullOrEmpty(namespace), "namespace can not be empty!");
Preconditions.checkArgument(!Strings.isNullOrEmpty(configId), "configId can not be empty!");

String configHistoryIdxKey = ConfigKeyGenerator.getConfigHistoryIdxKey(namespace, configId);
return redisCommands.zrevrange(configHistoryIdxKey, 0, HISTORY_STOP)
.thenApply(configHistoryKeyList ->
configHistoryKeyList.stream()
Expand All @@ -156,12 +178,15 @@ public CompletableFuture<List<ConfigVersion>> getConfigVersions(String namespace

@Override
public CompletableFuture<ConfigHistory> getConfigHistory(String configId, int version) {
return getConfigHistory(NamespacedContext.GLOBAL.getNamespace(), configId, version);
return getConfigHistory(NamespacedContext.GLOBAL.getRequiredNamespace(), configId, version);
}

@Override
public CompletableFuture<ConfigHistory> getConfigHistory(String namespace, String configId, int version) {
var configHistoryKey = ConfigKeyGenerator.getConfigHistoryKey(namespace, configId, version);
Preconditions.checkArgument(!Strings.isNullOrEmpty(namespace), "namespace can not be empty!");
Preconditions.checkArgument(!Strings.isNullOrEmpty(configId), "configId can not be empty!");

String configHistoryKey = ConfigKeyGenerator.getConfigHistoryKey(namespace, configId, version);
return getAndDecodeConfig(configHistoryKey, ConfigCodec::decodeHistory);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ public interface Namespaced {
* @return
*/
String getNamespace();

}
10 changes: 10 additions & 0 deletions cosky-core/src/main/java/me/ahoo/cosky/core/NamespacedContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

package me.ahoo.cosky.core;

import com.google.common.base.Strings;

/**
* @author ahoo wang
*/
Expand All @@ -30,6 +32,14 @@ public interface NamespacedContext extends Namespaced {
*/
void setCurrentContextNamespace(String namespace);

default String getRequiredNamespace() {
final String namespace = getNamespace();
if (Strings.isNullOrEmpty(namespace)) {
throw new CoskyException("namespace can not be empty!");
}
return namespace;
}

static NamespacedContext of(String namespace) {
return new Default(namespace);
}
Expand Down
Loading

0 comments on commit 6d18e2d

Please sign in to comment.