Skip to content

Commit 832b266

Browse files
committed
feat(redis): add initial Redis support (beta)
1 parent 227560c commit 832b266

File tree

9 files changed

+1026
-3
lines changed

9 files changed

+1026
-3
lines changed

networkdataapi-core/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@
2323
<artifactId>mongodb-driver-sync</artifactId>
2424
</dependency>
2525

26+
<!-- Redis (Jedis) -->
27+
<dependency>
28+
<groupId>redis.clients</groupId>
29+
<artifactId>jedis</artifactId>
30+
</dependency>
31+
2632
<!-- Caffeine Cache -->
2733
<dependency>
2834
<groupId>com.github.ben-manes.caffeine</groupId>

networkdataapi-core/src/main/java/com/astroid/stijnjakobs/networkdataapi/core/CoreManager.java

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
import com.astroid.stijnjakobs.networkdataapi.core.config.ConfigurationManager;
66
import com.astroid.stijnjakobs.networkdataapi.core.database.DatabaseManager;
77
import com.astroid.stijnjakobs.networkdataapi.core.environment.EnvironmentDetector;
8+
import com.astroid.stijnjakobs.networkdataapi.core.redis.RedisManager;
89
import com.astroid.stijnjakobs.networkdataapi.core.rest.RESTApiService;
910
import com.astroid.stijnjakobs.networkdataapi.core.service.PlayerDataService;
11+
import com.astroid.stijnjakobs.networkdataapi.core.service.RedisDataService;
1012
import lombok.Getter;
1113
import org.slf4j.Logger;
1214
import org.slf4j.LoggerFactory;
@@ -44,9 +46,11 @@ public class CoreManager {
4446

4547
private ConfigurationManager configurationManager;
4648
private DatabaseManager databaseManager;
49+
private RedisManager redisManager;
4750
private CacheManager cacheManager;
4851
private AsyncExecutor asyncExecutor;
4952
private PlayerDataService playerDataService;
53+
private RedisDataService redisDataService;
5054
private RESTApiService restApiService;
5155

5256
private boolean initialized = false;
@@ -90,6 +94,19 @@ public void initialize(File dataFolder) throws Exception {
9094
databaseManager = new DatabaseManager(configurationManager);
9195
databaseManager.connect();
9296

97+
// Initialize Redis manager (if enabled)
98+
if (configurationManager.getBoolean("redis.enabled", false)) {
99+
logger.info("Connecting to Redis...");
100+
redisManager = new RedisManager(configurationManager);
101+
redisManager.connect();
102+
103+
// Initialize Redis data service
104+
logger.info("Initializing Redis data service...");
105+
redisDataService = new RedisDataService(redisManager, asyncExecutor);
106+
} else {
107+
logger.info("Redis is disabled in configuration");
108+
}
109+
93110
// Initialize services
94111
logger.info("Initializing player data service...");
95112
playerDataService = new PlayerDataService(databaseManager, cacheManager, asyncExecutor);
@@ -132,6 +149,15 @@ private void scheduleMaintenanceTasks() {
132149
databaseManager.reconnect();
133150
}
134151
}, 1, TimeUnit.MINUTES);
152+
153+
// Redis health check every minute (if enabled)
154+
if (redisManager != null) {
155+
asyncExecutor.schedule(() -> {
156+
if (!redisManager.isAlive()) {
157+
logger.warn("Redis health check failed");
158+
}
159+
}, 1, TimeUnit.MINUTES);
160+
}
135161
}
136162

137163
/**
@@ -163,7 +189,16 @@ public void shutdown() {
163189
try {
164190
databaseManager.shutdown();
165191
} catch (Exception e) {
166-
logger.error("Error closing database connection", e);
192+
logger.error("Error shutting down database", e);
193+
}
194+
}
195+
196+
// Close Redis connection
197+
if (redisManager != null) {
198+
try {
199+
redisManager.shutdown();
200+
} catch (Exception e) {
201+
logger.error("Error shutting down Redis", e);
167202
}
168203
}
169204

@@ -188,5 +223,77 @@ public void shutdown() {
188223
public boolean isInitialized() {
189224
return initialized;
190225
}
226+
227+
/**
228+
* Gets the configuration manager.
229+
*
230+
* @return the configuration manager
231+
*/
232+
public ConfigurationManager getConfigurationManager() {
233+
return configurationManager;
234+
}
235+
236+
/**
237+
* Gets the database manager.
238+
*
239+
* @return the database manager
240+
*/
241+
public DatabaseManager getDatabaseManager() {
242+
return databaseManager;
243+
}
244+
245+
/**
246+
* Gets the Redis manager.
247+
*
248+
* @return the Redis manager
249+
*/
250+
public RedisManager getRedisManager() {
251+
return redisManager;
252+
}
253+
254+
/**
255+
* Gets the cache manager.
256+
*
257+
* @return the cache manager
258+
*/
259+
public CacheManager getCacheManager() {
260+
return cacheManager;
261+
}
262+
263+
/**
264+
* Gets the async executor.
265+
*
266+
* @return the async executor
267+
*/
268+
public AsyncExecutor getAsyncExecutor() {
269+
return asyncExecutor;
270+
}
271+
272+
/**
273+
* Gets the player data service.
274+
*
275+
* @return the player data service
276+
*/
277+
public PlayerDataService getPlayerDataService() {
278+
return playerDataService;
279+
}
280+
281+
/**
282+
* Gets the Redis data service.
283+
*
284+
* @return the Redis data service
285+
*/
286+
public RedisDataService getRedisDataService() {
287+
return redisDataService;
288+
}
289+
290+
/**
291+
* Gets the REST API service.
292+
*
293+
* @return the REST API service
294+
*/
295+
public RESTApiService getRestApiService() {
296+
return restApiService;
297+
}
191298
}
192299

networkdataapi-core/src/main/java/com/astroid/stijnjakobs/networkdataapi/core/api/APIRegistry.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import com.astroid.stijnjakobs.networkdataapi.core.CoreManager;
44
import com.astroid.stijnjakobs.networkdataapi.core.service.PlayerDataService;
5+
import com.astroid.stijnjakobs.networkdataapi.core.service.RedisDataService;
6+
import redis.clients.jedis.JedisPool;
57

68
/**
79
* Public API registry for accessing NetworkDataAPI services.
@@ -107,5 +109,24 @@ public String getVersion() {
107109
public boolean isHealthy() {
108110
return coreManager.getDatabaseManager().isHealthy();
109111
}
112+
113+
@Override
114+
public RedisDataService getRedisDataService() {
115+
return coreManager.getRedisDataService();
116+
}
117+
118+
@Override
119+
public JedisPool getRedisPool() {
120+
if (coreManager.getRedisManager() == null) {
121+
return null;
122+
}
123+
return coreManager.getRedisManager().getJedisPool();
124+
}
125+
126+
@Override
127+
public boolean isRedisEnabled() {
128+
return coreManager.getRedisManager() != null &&
129+
coreManager.getRedisManager().isConnected();
130+
}
110131
}
111132
}

networkdataapi-core/src/main/java/com/astroid/stijnjakobs/networkdataapi/core/api/NetworkDataAPIProvider.java

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package com.astroid.stijnjakobs.networkdataapi.core.api;
22

33
import com.astroid.stijnjakobs.networkdataapi.core.service.PlayerDataService;
4+
import com.astroid.stijnjakobs.networkdataapi.core.service.RedisDataService;
45
import com.mongodb.client.MongoDatabase;
6+
import redis.clients.jedis.JedisPool;
57

68
/**
79
* Public API interface for NetworkDataAPI.
@@ -139,4 +141,76 @@ public interface NetworkDataAPIProvider {
139141
* @return true if healthy, false otherwise
140142
*/
141143
boolean isHealthy();
144+
145+
/**
146+
* Gets the Redis data service for caching and messaging.
147+
*
148+
* <p>The Redis data service provides methods for:</p>
149+
* <ul>
150+
* <li>String operations (get, set, with TTL)</li>
151+
* <li>Hash operations (field-value storage)</li>
152+
* <li>Set operations (unique members)</li>
153+
* <li>List operations (ordered data)</li>
154+
* <li>Pub/Sub messaging</li>
155+
* <li>Counter operations</li>
156+
* </ul>
157+
*
158+
* <p><strong>Example - Caching player data:</strong></p>
159+
* <pre>{@code
160+
* RedisDataService redis = api.getRedisDataService();
161+
*
162+
* // Cache with 5 minute TTL
163+
* redis.setWithExpiry("player:" + uuid, playerData, 300);
164+
*
165+
* // Retrieve cached data
166+
* String data = redis.get("player:" + uuid);
167+
* }</pre>
168+
*
169+
* <p><strong>Example - Pub/Sub messaging:</strong></p>
170+
* <pre>{@code
171+
* // Publish to other servers
172+
* redis.publish("player-join", uuid.toString());
173+
* }</pre>
174+
*
175+
* @return the Redis data service, or null if Redis is disabled
176+
*/
177+
RedisDataService getRedisDataService();
178+
179+
/**
180+
* Gets direct access to the Redis connection pool.
181+
*
182+
* <p>This allows plugins to use the shared Redis connection pool
183+
* for custom operations not covered by RedisDataService.</p>
184+
*
185+
* <p><strong>Example - Custom Redis operations:</strong></p>
186+
* <pre>{@code
187+
* JedisPool pool = api.getRedisPool();
188+
* try (Jedis jedis = pool.getResource()) {
189+
* // Custom Redis commands
190+
* jedis.zadd("leaderboard", 1000, "player1");
191+
* Set<String> top10 = jedis.zrevrange("leaderboard", 0, 9);
192+
* }
193+
* }</pre>
194+
*
195+
* <p><strong>Benefits:</strong></p>
196+
* <ul>
197+
* <li>No separate Redis connection needed</li>
198+
* <li>Uses shared connection pool (efficient)</li>
199+
* <li>Automatic reconnection</li>
200+
* <li>Full Jedis API access</li>
201+
* </ul>
202+
*
203+
* <p><strong>Important:</strong> Always use try-with-resources to ensure
204+
* connections are returned to the pool!</p>
205+
*
206+
* @return the Jedis pool, or null if Redis is disabled
207+
*/
208+
JedisPool getRedisPool();
209+
210+
/**
211+
* Checks if Redis is enabled and connected.
212+
*
213+
* @return true if Redis is available
214+
*/
215+
boolean isRedisEnabled();
142216
}

networkdataapi-core/src/main/java/com/astroid/stijnjakobs/networkdataapi/core/config/ConfigurationManager.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,26 @@ private void createDefaultConfig() throws IOException {
7171
max-connection-idle-time-ms: 60000
7272
max-connection-life-time-ms: 600000
7373
74+
# Redis Connection Settings
75+
redis:
76+
enabled: false
77+
host: "localhost"
78+
port: 6379
79+
password: ""
80+
database: 0
81+
timeout-ms: 2000
82+
# Connection pool settings
83+
max-pool-size: 100
84+
max-idle: 50
85+
min-idle: 10
86+
test-on-borrow: true
87+
test-on-return: false
88+
test-while-idle: true
89+
min-evictable-idle-time-ms: 60000
90+
time-between-eviction-runs-ms: 30000
91+
block-when-exhausted: true
92+
max-wait-ms: 3000
93+
7494
# Cache Settings
7595
cache:
7696
enabled: true

networkdataapi-core/src/main/java/com/astroid/stijnjakobs/networkdataapi/core/database/DatabaseManager.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,8 @@ public class DatabaseManager {
4141

4242
private MongoClient mongoClient;
4343

44-
@Getter
4544
private MongoDatabase database;
4645

47-
@Getter
4846
private boolean connected = false;
4947

5048
private final ConfigurationManager config;
@@ -58,6 +56,24 @@ public DatabaseManager(ConfigurationManager config) {
5856
this.config = config;
5957
}
6058

59+
/**
60+
* Gets the MongoDB database instance.
61+
*
62+
* @return the MongoDatabase instance
63+
*/
64+
public MongoDatabase getDatabase() {
65+
return database;
66+
}
67+
68+
/**
69+
* Checks if the database is connected.
70+
*
71+
* @return true if connected, false otherwise
72+
*/
73+
public boolean isConnected() {
74+
return connected;
75+
}
76+
6177
/**
6278
* Initializes the database connection.
6379
*

0 commit comments

Comments
 (0)