From df7d2d426958906305344f12f5c457347b147127 Mon Sep 17 00:00:00 2001 From: dengliming Date: Fri, 3 May 2024 23:20:21 +0800 Subject: [PATCH] Add support springboot starter --- README.md | 5 + pom.xml | 25 ++- spring-boot-starter/README.md | 56 +++++++ spring-boot-starter/pom.xml | 60 ++++++++ .../RedisModuleAutoConfiguration.java | 145 ++++++++++++++++++ .../starter/env/RedisModuleProperties.java | 120 +++++++++++++++ .../main/resources/META-INF/spring.factories | 2 + .../springboot/starter/RedisJSONTest.java | 46 ++++++ .../springboot/starter/RedisModuleTest.java | 27 ++++ .../test/resources/application-redisearch.yml | 24 +++ .../test/resources/application-redisjson.yml | 24 +++ .../src/test/resources/application.yml | 2 + 12 files changed, 535 insertions(+), 1 deletion(-) create mode 100644 spring-boot-starter/README.md create mode 100644 spring-boot-starter/pom.xml create mode 100644 spring-boot-starter/src/main/java/io/github/dengliming/redismodule/springboot/starter/autoconfigure/RedisModuleAutoConfiguration.java create mode 100644 spring-boot-starter/src/main/java/io/github/dengliming/redismodule/springboot/starter/env/RedisModuleProperties.java create mode 100644 spring-boot-starter/src/main/resources/META-INF/spring.factories create mode 100644 spring-boot-starter/src/test/java/io/github/dengliming/redismodule/springboot/starter/RedisJSONTest.java create mode 100644 spring-boot-starter/src/test/java/io/github/dengliming/redismodule/springboot/starter/RedisModuleTest.java create mode 100644 spring-boot-starter/src/test/resources/application-redisearch.yml create mode 100644 spring-boot-starter/src/test/resources/application-redisjson.yml create mode 100644 spring-boot-starter/src/test/resources/application.yml diff --git a/README.md b/README.md index 5e00546..cdc831f 100644 --- a/README.md +++ b/README.md @@ -154,6 +154,11 @@ redisJSON.set(key, SetArgs.Builder.create(".", GsonUtils.toJson(m))); Map actual = redisJSON.get(key, Map.class, new GetArgs().path(".").indent("\t").newLine("\n").space(" ")); redisJSONClient.shutdown(); ``` + +SpringBoot Starter + +see [spring-boot-starter](./spring-boot-starter) + ## License [Apache License 2.0](/LICENSE) diff --git a/pom.xml b/pom.xml index 423957e..3df37b6 100644 --- a/pom.xml +++ b/pom.xml @@ -18,6 +18,7 @@ redisjson redisgraph commons + spring-boot-starter Redis-Modules-Java @@ -53,7 +54,7 @@ UTF-8 3.27.1 - 5.6.2 + 5.6.3 1.8 3.0.1 3.2.1 @@ -67,6 +68,7 @@ 3.1.0 3.8.1 2.4 + 2.7.6 @@ -118,6 +120,27 @@ redisgraph ${project.version} + + + io.github.dengliming.redismodule + spring-boot-starter + ${project.version} + + + + io.github.dengliming.redismodule + all + ${project.version} + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + diff --git a/spring-boot-starter/README.md b/spring-boot-starter/README.md new file mode 100644 index 0000000..d88eabf --- /dev/null +++ b/spring-boot-starter/README.md @@ -0,0 +1,56 @@ +# SpringBoot Starter + + +## Usage + +Add dependency +```xml + + + io.github.dengliming.redismodule + spring-boot-starter + 2.0.4-SNAPSHOT + + +``` + +RedisJSON +```yaml +redis-module: + enabled: true + redisjson: + enabled: true + config: | + singleServerConfig: + idleConnectionTimeout: 10000 + connectTimeout: 10000 + timeout: 3000 + retryAttempts: 3 + retryInterval: 1500 + password: null + subscriptionsPerConnection: 5 + clientName: null + address: "redis://127.0.0.1:6379" + subscriptionConnectionMinimumIdleSize: 1 + subscriptionConnectionPoolSize: 50 + connectionMinimumIdleSize: 24 + connectionPoolSize: 64 + database: 0 + dnsMonitoringInterval: 5000 + threads: 16 + nettyThreads: 32 + codec: ! {} + transportMode: "NIO" +``` + +Use in Spring +```java +@Autowired(required = false) +private RedisJSONClient redisJSONClient; + +public void test() { + RedisJSON redisJSON = redisJSONClient.getRedisJSON(); + String key = "foo"; + redisJSON.set(key, SetArgs.Builder.create(".", "\"bar\"")); +} +``` \ No newline at end of file diff --git a/spring-boot-starter/pom.xml b/spring-boot-starter/pom.xml new file mode 100644 index 0000000..9eaaf24 --- /dev/null +++ b/spring-boot-starter/pom.xml @@ -0,0 +1,60 @@ + + 4.0.0 + + io.github.dengliming.redismodule + redis-modules-java + 2.0.4-SNAPSHOT + + + spring-boot-starter + SpringBootStarter + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + + + + org.springframework.boot + spring-boot-autoconfigure + provided + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + org.springframework.boot + spring-boot-starter-test + + + org.junit.vintage + junit-vintage-engine + + + test + + + + io.github.dengliming.redismodule + commons + + + + io.github.dengliming.redismodule + all + + + diff --git a/spring-boot-starter/src/main/java/io/github/dengliming/redismodule/springboot/starter/autoconfigure/RedisModuleAutoConfiguration.java b/spring-boot-starter/src/main/java/io/github/dengliming/redismodule/springboot/starter/autoconfigure/RedisModuleAutoConfiguration.java new file mode 100644 index 0000000..a74fc54 --- /dev/null +++ b/spring-boot-starter/src/main/java/io/github/dengliming/redismodule/springboot/starter/autoconfigure/RedisModuleAutoConfiguration.java @@ -0,0 +1,145 @@ +/* + * Copyright 2024 dengliming. + * + * 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.github.dengliming.redismodule.springboot.starter.autoconfigure; + +import io.github.dengliming.redismodule.redisai.client.RedisAIClient; +import io.github.dengliming.redismodule.redisbloom.client.RedisBloomClient; +import io.github.dengliming.redismodule.redisearch.client.RediSearchClient; +import io.github.dengliming.redismodule.redisgears.client.RedisGearsClient; +import io.github.dengliming.redismodule.redisgraph.client.RedisGraphClient; +import io.github.dengliming.redismodule.redisjson.client.RedisJSONClient; +import io.github.dengliming.redismodule.redistimeseries.client.RedisTimeSeriesClient; +import io.github.dengliming.redismodule.springboot.starter.env.RedisModuleProperties; +import org.redisson.Redisson; +import org.redisson.config.Config; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.io.IOException; + +@ConditionalOnProperty( + prefix = RedisModuleProperties.PREFIX, + name = "enabled", + havingValue = "true", + matchIfMissing = true +) +@ConditionalOnClass(Redisson.class) +@EnableConfigurationProperties(RedisModuleProperties.class) +@Configuration +public class RedisModuleAutoConfiguration { + private final RedisModuleProperties redisModuleProperties; + + public RedisModuleAutoConfiguration(RedisModuleProperties redisModuleProperties) { + this.redisModuleProperties = redisModuleProperties; + } + + @ConditionalOnProperty( + prefix = RedisModuleProperties.PREFIX + ".redisearch", + name = "enabled", + havingValue = "true" + ) + @Bean(destroyMethod = "shutdown") + @ConditionalOnMissingBean + public RediSearchClient rediSearchClient() { + return new RediSearchClient(parseRedisModuleConfig(redisModuleProperties.getRedisearch().getConfig())); + } + + @ConditionalOnProperty( + prefix = RedisModuleProperties.PREFIX + ".redisai", + name = "enabled", + havingValue = "true" + ) + @Bean(destroyMethod = "shutdown") + @ConditionalOnMissingBean + public RedisAIClient redisAIClient() { + return new RedisAIClient(parseRedisModuleConfig(redisModuleProperties.getRedisai().getConfig())); + } + + @ConditionalOnProperty( + prefix = RedisModuleProperties.PREFIX + ".redisbloom", + name = "enabled", + havingValue = "true" + ) + @Bean(destroyMethod = "shutdown") + @ConditionalOnMissingBean + public RedisBloomClient redisBloomClient() { + return new RedisBloomClient(parseRedisModuleConfig(redisModuleProperties.getRedisbloom().getConfig())); + } + + @ConditionalOnProperty( + prefix = RedisModuleProperties.PREFIX + ".redisgears", + name = "enabled", + havingValue = "true" + ) + @Bean(destroyMethod = "shutdown") + @ConditionalOnMissingBean + public RedisGearsClient redisGearsClient() { + return new RedisGearsClient(parseRedisModuleConfig(redisModuleProperties.getRedisgears().getConfig())); + } + + @ConditionalOnProperty( + prefix = RedisModuleProperties.PREFIX + ".redisgraph", + name = "enabled", + havingValue = "true" + ) + @Bean(destroyMethod = "shutdown") + @ConditionalOnMissingBean + public RedisGraphClient redisGraphClient() { + return new RedisGraphClient(parseRedisModuleConfig(redisModuleProperties.getRedisgraph().getConfig())); + } + + @ConditionalOnProperty( + prefix = RedisModuleProperties.PREFIX + ".redisjson", + name = "enabled", + havingValue = "true" + ) + @Bean(destroyMethod = "shutdown") + @ConditionalOnMissingBean + public RedisJSONClient redisJSONClient() { + return new RedisJSONClient(parseRedisModuleConfig(redisModuleProperties.getRedisjson().getConfig())); + } + + @ConditionalOnProperty( + prefix = RedisModuleProperties.PREFIX + ".redistimeseries", + name = "enabled", + havingValue = "true" + ) + @Bean(destroyMethod = "shutdown") + @ConditionalOnMissingBean + public RedisTimeSeriesClient redisTimeSeriesClient() { + return new RedisTimeSeriesClient(parseRedisModuleConfig(redisModuleProperties.getRedistimeseries().getConfig())); + } + + private Config parseRedisModuleConfig(String configStr) { + Config config; + try { + config = Config.fromYAML(configStr); + } catch (IOException e) { + try { + config = Config.fromJSON(configStr); + } catch (IOException ex) { + ex.addSuppressed(e); + throw new IllegalArgumentException("Can't parse config", ex); + } + } + return config; + } +} diff --git a/spring-boot-starter/src/main/java/io/github/dengliming/redismodule/springboot/starter/env/RedisModuleProperties.java b/spring-boot-starter/src/main/java/io/github/dengliming/redismodule/springboot/starter/env/RedisModuleProperties.java new file mode 100644 index 0000000..2d29494 --- /dev/null +++ b/spring-boot-starter/src/main/java/io/github/dengliming/redismodule/springboot/starter/env/RedisModuleProperties.java @@ -0,0 +1,120 @@ +/* + * Copyright 2024 dengliming. + * + * 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.github.dengliming.redismodule.springboot.starter.env; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties(prefix = RedisModuleProperties.PREFIX) +public class RedisModuleProperties { + public static final String PREFIX = "redis-module"; + + private boolean enabled; + private RedisModuleConfig redisai; + private RedisModuleConfig redisbloom; + private RedisModuleConfig redisearch; + private RedisModuleConfig redisgears; + private RedisModuleConfig redisgraph; + private RedisModuleConfig redisjson; + private RedisModuleConfig redistimeseries; + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public RedisModuleConfig getRedisai() { + return redisai; + } + + public void setRedisai(RedisModuleConfig redisai) { + this.redisai = redisai; + } + + public RedisModuleConfig getRedisbloom() { + return redisbloom; + } + + public void setRedisbloom(RedisModuleConfig redisbloom) { + this.redisbloom = redisbloom; + } + + public RedisModuleConfig getRedisearch() { + return redisearch; + } + + public void setRedisearch(RedisModuleConfig redisearch) { + this.redisearch = redisearch; + } + + public RedisModuleConfig getRedisgears() { + return redisgears; + } + + public void setRedisgears(RedisModuleConfig redisgears) { + this.redisgears = redisgears; + } + + public RedisModuleConfig getRedisgraph() { + return redisgraph; + } + + public void setRedisgraph(RedisModuleConfig redisgraph) { + this.redisgraph = redisgraph; + } + + public RedisModuleConfig getRedisjson() { + return redisjson; + } + + public void setRedisjson(RedisModuleConfig redisjson) { + this.redisjson = redisjson; + } + + public RedisModuleConfig getRedistimeseries() { + return redistimeseries; + } + + public void setRedistimeseries(RedisModuleConfig redistimeseries) { + this.redistimeseries = redistimeseries; + } + + public static class RedisModuleConfig { + private boolean enabled; + private String config; + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public String getConfig() { + return config; + } + + public void setConfig(String config) { + this.config = config; + } + } +} diff --git a/spring-boot-starter/src/main/resources/META-INF/spring.factories b/spring-boot-starter/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..a0501b5 --- /dev/null +++ b/spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + io.github.dengliming.redismodule.springboot.starter.autoconfigure.RedisModuleAutoConfiguration \ No newline at end of file diff --git a/spring-boot-starter/src/test/java/io/github/dengliming/redismodule/springboot/starter/RedisJSONTest.java b/spring-boot-starter/src/test/java/io/github/dengliming/redismodule/springboot/starter/RedisJSONTest.java new file mode 100644 index 0000000..f871ac7 --- /dev/null +++ b/spring-boot-starter/src/test/java/io/github/dengliming/redismodule/springboot/starter/RedisJSONTest.java @@ -0,0 +1,46 @@ +/* + * Copyright 2024 dengliming. + * + * 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.github.dengliming.redismodule.springboot.starter; + +import io.github.dengliming.redismodule.redisjson.RedisJSON; +import io.github.dengliming.redismodule.redisjson.args.SetArgs; +import io.github.dengliming.redismodule.redisjson.client.RedisJSONClient; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ActiveProfiles; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author dengliming + */ +@ActiveProfiles("redisjson") +public class RedisJSONTest extends RedisModuleTest { + + @Autowired(required = false) + private RedisJSONClient redisJSONClient; + + @Test + public void test() { + RedisJSON redisJSON = redisJSONClient.getRedisJSON(); + String key = "foo"; + assertThat(redisJSON.set(key, SetArgs.Builder.create(".", "\"bar\""))).isEqualTo("OK"); + assertThat(redisJSON.set(key, SetArgs.Builder.nx(".", "\"bar\""))).isNull(); + assertThat(redisJSON.set(key, SetArgs.Builder.xx(".", "\"bar\""))).isEqualTo("OK"); + assertThat(redisJSON.del(key, ".")).isEqualTo(1); + } +} diff --git a/spring-boot-starter/src/test/java/io/github/dengliming/redismodule/springboot/starter/RedisModuleTest.java b/spring-boot-starter/src/test/java/io/github/dengliming/redismodule/springboot/starter/RedisModuleTest.java new file mode 100644 index 0000000..44acd16 --- /dev/null +++ b/spring-boot-starter/src/test/java/io/github/dengliming/redismodule/springboot/starter/RedisModuleTest.java @@ -0,0 +1,27 @@ +/* + * Copyright 2024 dengliming. + * + * 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.github.dengliming.redismodule.springboot.starter; + +import io.github.dengliming.redismodule.springboot.starter.autoconfigure.RedisModuleAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; + +/** + * @author dengliming + */ +@SpringBootTest(classes = RedisModuleAutoConfiguration.class) +public abstract class RedisModuleTest { +} diff --git a/spring-boot-starter/src/test/resources/application-redisearch.yml b/spring-boot-starter/src/test/resources/application-redisearch.yml new file mode 100644 index 0000000..64ff78d --- /dev/null +++ b/spring-boot-starter/src/test/resources/application-redisearch.yml @@ -0,0 +1,24 @@ +redis-module: + redisearch: + enabled: true + config: | + singleServerConfig: + idleConnectionTimeout: 10000 + connectTimeout: 10000 + timeout: 3000 + retryAttempts: 3 + retryInterval: 1500 + password: null + subscriptionsPerConnection: 5 + clientName: null + address: "redis://127.0.0.1:6379" + subscriptionConnectionMinimumIdleSize: 1 + subscriptionConnectionPoolSize: 50 + connectionMinimumIdleSize: 24 + connectionPoolSize: 64 + database: 0 + dnsMonitoringInterval: 5000 + threads: 16 + nettyThreads: 32 + codec: ! {} + transportMode: "NIO" \ No newline at end of file diff --git a/spring-boot-starter/src/test/resources/application-redisjson.yml b/spring-boot-starter/src/test/resources/application-redisjson.yml new file mode 100644 index 0000000..962cdcd --- /dev/null +++ b/spring-boot-starter/src/test/resources/application-redisjson.yml @@ -0,0 +1,24 @@ +redis-module: + redisjson: + enabled: true + config: | + singleServerConfig: + idleConnectionTimeout: 10000 + connectTimeout: 10000 + timeout: 3000 + retryAttempts: 3 + retryInterval: 1500 + password: null + subscriptionsPerConnection: 5 + clientName: null + address: "redis://127.0.0.1:6379" + subscriptionConnectionMinimumIdleSize: 1 + subscriptionConnectionPoolSize: 50 + connectionMinimumIdleSize: 24 + connectionPoolSize: 64 + database: 0 + dnsMonitoringInterval: 5000 + threads: 16 + nettyThreads: 32 + codec: ! {} + transportMode: "NIO" \ No newline at end of file diff --git a/spring-boot-starter/src/test/resources/application.yml b/spring-boot-starter/src/test/resources/application.yml new file mode 100644 index 0000000..66b637d --- /dev/null +++ b/spring-boot-starter/src/test/resources/application.yml @@ -0,0 +1,2 @@ +redis-module: + enabled: true \ No newline at end of file