Skip to content

Commit 89e1482

Browse files
committed
feat: add CommandListener support and NoOpCommandListener implementation for Redis command monitoring
1 parent 60a273f commit 89e1482

File tree

4 files changed

+86
-60
lines changed

4 files changed

+86
-60
lines changed

redis-om-spring/src/main/java/com/redis/om/spring/RedisModulesConfiguration.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import java.util.List;
99
import java.util.Set;
1010

11+
import com.redis.om.spring.ops.CommandListener;
12+
import com.redis.om.spring.ops.NoOpCommandListener;
1113
import org.apache.commons.lang3.ObjectUtils;
1214
import org.apache.commons.logging.Log;
1315
import org.apache.commons.logging.LogFactory;
@@ -202,6 +204,7 @@ RedisModulesClient redisModulesClient( //
202204
* @param rmc the Redis modules client for low-level access
203205
* @param template the string Redis template for basic operations
204206
* @param gsonBuilder the Gson builder for JSON serialization
207+
* @param commandListener a command listener for monitoring Redis commands
205208
* @return the Redis modules operations instance
206209
*/
207210
@Bean(
@@ -215,10 +218,28 @@ RedisModulesOperations<?> redisModulesOperations( //
215218
StringRedisTemplate template, //
216219
@Qualifier(
217220
"omGsonBuilder"
218-
) GsonBuilder gsonBuilder) {
219-
return new RedisModulesOperations<>(rmc, template, gsonBuilder);
221+
) GsonBuilder gsonBuilder, final CommandListener commandListener) {
222+
return new RedisModulesOperations<>(rmc, template, gsonBuilder, commandListener);
220223
}
221224

225+
/**
226+
* Provides a default implementation of the CommandListener bean.
227+
* <p>
228+
* This method creates a no-operation (NoOp) implementation of the CommandListener interface.
229+
* It is used as a fallback when no other CommandListener bean is defined in the application context.
230+
* <p>
231+
* The {@code @Fallback} annotation ensures that this bean is only used when no other
232+
* CommandListener bean is available, allowing developers to override it with a custom implementation if needed.
233+
*
234+
* @return a NoOpCommandListener instance, which performs no operations.
235+
*/
236+
@Bean
237+
@Fallback
238+
public CommandListener commandListener() {
239+
return new NoOpCommandListener();
240+
}
241+
242+
222243
/**
223244
* Creates the JSON operations bean for RedisJSON commands.
224245
* <p>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.redis.om.spring.ops;
2+
3+
import org.springframework.stereotype.Component;
4+
5+
@Component
6+
public class NoOpCommandListener implements CommandListener {
7+
}

redis-om-spring/src/main/java/com/redis/om/spring/ops/RedisModulesOperations.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import com.redis.om.spring.ops.pds.*;
1010
import com.redis.om.spring.ops.search.SearchOperations;
1111
import com.redis.om.spring.ops.search.SearchOperationsImpl;
12-
import java.util.Optional;
1312

1413
/**
1514
* A record that provides centralized access to Redis module operations.
@@ -27,7 +26,7 @@
2726
* @param client the Redis modules client for executing commands
2827
* @param template the Spring Data Redis template for additional Redis operations
2928
* @param gsonBuilder the Gson builder for JSON serialization/deserialization configuration
30-
* @param commandListener An optional command listener for monitoring Redis commands
29+
* @param commandListener A command listener for monitoring Redis commands
3130
*
3231
* @author Redis OM Spring Team
3332
* @see JSONOperations
@@ -39,7 +38,7 @@
3938
* @see TDigestOperations
4039
*/
4140
public record RedisModulesOperations<K>(RedisModulesClient client, StringRedisTemplate template,
42-
GsonBuilder gsonBuilder, Optional<CommandListener> commandListener) {
41+
GsonBuilder gsonBuilder, CommandListener commandListener) {
4342

4443
/**
4544
* Creates and returns operations for interacting with RedisJSON module.

redis-om-spring/src/main/java/com/redis/om/spring/ops/search/SearchOperationsImpl.java

Lines changed: 54 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import java.util.List;
44
import java.util.Map;
5-
import java.util.Optional;
65
import java.util.Set;
76
import com.redis.om.spring.ops.CommandListener;
87
import org.springframework.data.redis.core.StringRedisTemplate;
@@ -40,18 +39,18 @@ public class SearchOperationsImpl<K> implements SearchOperations<K> {
4039
private final RedisModulesClient modulesClient;
4140
private final K index;
4241
private final StringRedisTemplate template;
43-
private final Optional<CommandListener> commandListener;
42+
private final CommandListener commandListener;
4443

4544
/**
4645
* Creates a new search operations implementation.
4746
*
4847
* @param index the search index identifier
4948
* @param modulesClient the Redis modules client for search operations
5049
* @param template the string Redis template for additional operations
51-
* @param commandListener An optional command listener for monitoring Redis commands
50+
* @param commandListener A command listener for monitoring Redis commands
5251
*/
5352
public SearchOperationsImpl(K index, RedisModulesClient modulesClient, StringRedisTemplate template,
54-
final Optional<CommandListener> commandListener) {
53+
final CommandListener commandListener) {
5554
this.index = index;
5655
this.modulesClient = modulesClient;
5756
this.search = modulesClient.clientForSearch();
@@ -61,90 +60,90 @@ public SearchOperationsImpl(K index, RedisModulesClient modulesClient, StringRed
6160

6261
@Override
6362
public String createIndex(Schema schema, IndexOptions options) {
64-
commandListener.ifPresent(it -> it.createIndexStarted(index.toString(), null, null, schema, options));
63+
commandListener.createIndexStarted(index.toString(), null, null, schema, options);
6564
final String s = search.ftCreate(index.toString(), options, schema);
66-
commandListener.ifPresent(it -> it.createIndexFinished(index.toString(), null, null, schema, options, s));
65+
commandListener.createIndexFinished(index.toString(), null, null, schema, options, s);
6766
return s;
6867
}
6968

7069
@Override
7170
public String createIndex(FTCreateParams params, List<SchemaField> fields) {
72-
commandListener.ifPresent(it -> it.createIndexStarted(index.toString(), params, fields, null, null));
71+
commandListener.createIndexStarted(index.toString(), params, fields, null, null);
7372
final String s = search.ftCreate(index.toString(), params, fields);
74-
commandListener.ifPresent(it -> it.createIndexFinished(index.toString(), params, fields, null, null, s));
73+
commandListener.createIndexFinished(index.toString(), params, fields, null, null, s);
7574
return s;
7675
}
7776

7877
@Override
7978
@Deprecated
8079
public SearchResult search(Query q) {
81-
commandListener.ifPresent(it -> it.searchStarted(index.toString(), q, null));
80+
commandListener.searchStarted(index.toString(), q, null);
8281
final SearchResult searchResult = search.ftSearch(SafeEncoder.encode(index.toString()), q);
83-
commandListener.ifPresent(it -> it.searchFinished(index.toString(), q, null, searchResult));
82+
commandListener.searchFinished(index.toString(), q, null, searchResult);
8483
return searchResult;
8584
}
8685

8786
@Override
8887
public SearchResult search(Query q, FTSearchParams params) {
89-
commandListener.ifPresent(it -> it.searchStarted(index.toString(), q, null));
88+
commandListener.searchStarted(index.toString(), q, null);
9089
final SearchResult searchResult = search.ftSearch(index.toString(), q.toString(), params);
91-
commandListener.ifPresent(it -> it.searchFinished(index.toString(), q, null, searchResult));
90+
commandListener.searchFinished(index.toString(), q, null, searchResult);
9291
return searchResult;
9392
}
9493

9594
@Override
9695
public AggregationResult aggregate(AggregationBuilder q) {
97-
commandListener.ifPresent(it -> it.aggregateStarted(index.toString(), q));
96+
commandListener.aggregateStarted(index.toString(), q);
9897
final AggregationResult aggregationResult = search.ftAggregate(index.toString(), q);
99-
commandListener.ifPresent(it -> it.aggregateFinished(index.toString(), q));
98+
commandListener.aggregateFinished(index.toString(), q);
10099
return aggregationResult;
101100
}
102101

103102
@Override
104103
public String cursorDelete(long cursorId) {
105-
commandListener.ifPresent(it -> it.cursorDeleteStarted(index.toString(), cursorId));
104+
commandListener.cursorDeleteStarted(index.toString(), cursorId);
106105
final String result = search.ftCursorDel(index.toString(), cursorId);
107-
commandListener.ifPresent(it -> it.cursorDeleteFinished(index.toString(), cursorId, result));
106+
commandListener.cursorDeleteFinished(index.toString(), cursorId, result);
108107
return result;
109108
}
110109

111110
@Override
112111
public AggregationResult cursorRead(long cursorId, int count) {
113-
commandListener.ifPresent(it -> it.cursorReadStarted(index.toString(), cursorId, count));
112+
commandListener.cursorReadStarted(index.toString(), cursorId, count);
114113
final AggregationResult aggregationResult = search.ftCursorRead(index.toString(), cursorId, count);
115-
commandListener.ifPresent(it -> it.cursorReadFinished(index.toString(), cursorId, count, aggregationResult));
114+
commandListener.cursorReadFinished(index.toString(), cursorId, count, aggregationResult);
116115
return aggregationResult;
117116
}
118117

119118
@Override
120119
public String explain(Query q) {
121-
commandListener.ifPresent(it -> it.explainStarted(index.toString(), q));
120+
commandListener.explainStarted(index.toString(), q);
122121
final String s = search.ftExplain(index.toString(), q);
123-
commandListener.ifPresent(it -> it.explainFinished(index.toString(), q, s));
122+
commandListener.explainFinished(index.toString(), q, s);
124123
return s;
125124
}
126125

127126
@Override
128127
public Map<String, Object> getInfo() {
129-
commandListener.ifPresent(it -> it.infoStarted(index.toString()));
128+
commandListener.infoStarted(index.toString());
130129
final Map<String, Object> result = search.ftInfo(index.toString());
131-
commandListener.ifPresent(it -> it.infoFinished(index.toString(), result));
130+
commandListener.infoFinished(index.toString(), result);
132131
return result;
133132
}
134133

135134
@Override
136135
public String dropIndex() {
137-
commandListener.ifPresent(it -> it.dropIndexStarted(index.toString()));
136+
commandListener.dropIndexStarted(index.toString());
138137
final String result = search.ftDropIndex(index.toString());
139-
commandListener.ifPresent(it -> it.dropIndexFinished(index.toString(), result));
138+
commandListener.dropIndexFinished(index.toString(), result);
140139
return result;
141140
}
142141

143142
@Override
144143
public String dropIndexAndDocuments() {
145-
commandListener.ifPresent(it -> it.dropIndexAndDocumentsStarted(index.toString()));
144+
commandListener.dropIndexAndDocumentsStarted(index.toString());
146145
final String result = search.ftDropIndexDD(index.toString());
147-
commandListener.ifPresent(it -> it.dropIndexAndDocumentsFinished(index.toString(), result));
146+
commandListener.dropIndexAndDocumentsFinished(index.toString(), result);
148147
return result;
149148
}
150149

@@ -155,9 +154,9 @@ public Long addSuggestion(String key, String suggestion) {
155154

156155
@Override
157156
public Long addSuggestion(String key, String suggestion, double score) {
158-
commandListener.ifPresent(it -> it.addSuggestionStarted(index.toString(), key, suggestion, score));
157+
commandListener.addSuggestionStarted(index.toString(), key, suggestion, score);
159158
final long result = search.ftSugAdd(key, suggestion, score);
160-
commandListener.ifPresent(it -> it.addSuggestionFinished(index.toString(), key, suggestion, score, result));
159+
commandListener.addSuggestionFinished(index.toString(), key, suggestion, score, result);
161160
return result;
162161
}
163162

@@ -168,7 +167,7 @@ public List<Suggestion> getSuggestion(String key, String prefix) {
168167

169168
@Override
170169
public List<Suggestion> getSuggestion(String key, String prefix, AutoCompleteOptions options) {
171-
commandListener.ifPresent(it -> it.getSuggestionStarted(index.toString(), key, prefix, options));
170+
commandListener.getSuggestionStarted(index.toString(), key, prefix, options);
172171
Gson gson = modulesClient.gsonBuilder().create();
173172

174173
if (options.isWithScore()) {
@@ -187,7 +186,7 @@ public List<Suggestion> getSuggestion(String key, String prefix, AutoCompleteOpt
187186
return new Suggestion(suggestion.getElement(), suggestion.getScore());
188187
}
189188
}).toList();
190-
commandListener.ifPresent(it -> it.getSuggestionFinished(index.toString(), key, prefix, options, list));
189+
commandListener.getSuggestionFinished(index.toString(), key, prefix, options, list);
191190
return list;
192191
} else {
193192
List<String> suggestions = search.ftSugGet(key, prefix, options.isFuzzy(), options.getLimit());
@@ -205,104 +204,104 @@ public List<Suggestion> getSuggestion(String key, String prefix, AutoCompleteOpt
205204
return new Suggestion(suggestion);
206205
}
207206
}).toList();
208-
commandListener.ifPresent(it -> it.getSuggestionFinished(index.toString(), key, prefix, options, list));
207+
commandListener.getSuggestionFinished(index.toString(), key, prefix, options, list);
209208
return list;
210209
}
211210
}
212211

213212
@Override
214213
public Boolean deleteSuggestion(String key, String entry) {
215-
commandListener.ifPresent(it -> it.deleteSuggestionStarted(index.toString(), key, entry));
214+
commandListener.deleteSuggestionStarted(index.toString(), key, entry);
216215
final boolean result = search.ftSugDel(key, entry);
217-
commandListener.ifPresent(it -> it.deleteSuggestionFinished(index.toString(), key, entry, result));
216+
commandListener.deleteSuggestionFinished(index.toString(), key, entry, result);
218217
return result;
219218
}
220219

221220
@Override
222221
public Long getSuggestionLength(String key) {
223-
commandListener.ifPresent(it -> it.getSuggestionLengthStarted(index.toString(), key));
222+
commandListener.getSuggestionLengthStarted(index.toString(), key);
224223
final long result = search.ftSugLen(key);
225-
commandListener.ifPresent(it -> it.getSuggestionLengthFinished(index.toString(), key, result));
224+
commandListener.getSuggestionLengthFinished(index.toString(), key, result);
226225
return result;
227226
}
228227

229228
@Override
230229
public String alterIndex(SchemaField... fields) {
231-
commandListener.ifPresent(it -> it.alterIndexStarted(index.toString(), fields));
230+
commandListener.alterIndexStarted(index.toString(), fields);
232231
final String result = search.ftAlter(index.toString(), fields);
233-
commandListener.ifPresent(it -> it.alterIndexFinished(index.toString(), fields, result));
232+
commandListener.alterIndexFinished(index.toString(), fields, result);
234233
return result;
235234
}
236235

237236
@Override
238237
public String setConfig(String option, String value) {
239-
commandListener.ifPresent(it -> it.setConfigStarted(index.toString(), option, value));
238+
commandListener.setConfigStarted(index.toString(), option, value);
240239
final String result = search.ftConfigSet(option, value);
241-
commandListener.ifPresent(it -> it.setConfigFinished(index.toString(), option, value, result));
240+
commandListener.setConfigFinished(index.toString(), option, value, result);
242241
return result;
243242
}
244243

245244
@Override
246245
public Map<String, Object> getConfig(String option) {
247-
commandListener.ifPresent(it -> it.getConfigStarted(index.toString(), option));
246+
commandListener.getConfigStarted(index.toString(), option);
248247
final Map<String, Object> result = search.ftConfigGet(option);
249-
commandListener.ifPresent(it -> it.getConfigFinished(index.toString(), option, result));
248+
commandListener.getConfigFinished(index.toString(), option, result);
250249
return result;
251250
}
252251

253252
@Override
254253
public Map<String, Object> getIndexConfig(String option) {
255-
commandListener.ifPresent(it -> it.getIndexConfigStarted(index.toString(), option));
254+
commandListener.getIndexConfigStarted(index.toString(), option);
256255
final Map<String, Object> result = search.ftConfigGet(index.toString(), option);
257-
commandListener.ifPresent(it -> it.getIndexConfigFinished(index.toString(), option, result));
256+
commandListener.getIndexConfigFinished(index.toString(), option, result);
258257
return result;
259258
}
260259

261260
@Override
262261
public String addAlias(String name) {
263-
commandListener.ifPresent(it -> it.addAliasStarted(index.toString(), name));
262+
commandListener.addAliasStarted(index.toString(), name);
264263
final String result = search.ftAliasAdd(name, index.toString());
265-
commandListener.ifPresent(it -> it.addAliasFinished(index.toString(), name, result));
264+
commandListener.addAliasFinished(index.toString(), name, result);
266265
return result;
267266
}
268267

269268
@Override
270269
public String updateAlias(String name) {
271-
commandListener.ifPresent(it -> it.updateAliasStarted(index.toString(), name));
270+
commandListener.updateAliasStarted(index.toString(), name);
272271
final String result = search.ftAliasUpdate(name, index.toString());
273-
commandListener.ifPresent(it -> it.updateAliasFinished(index.toString(), name, result));
272+
commandListener.updateAliasFinished(index.toString(), name, result);
274273
return result;
275274
}
276275

277276
@Override
278277
public String deleteAlias(String name) {
279-
commandListener.ifPresent(it -> it.deleteAliasStarted(index.toString(), name));
278+
commandListener.deleteAliasStarted(index.toString(), name);
280279
final String result = search.ftAliasDel(name);
281-
commandListener.ifPresent(it -> it.deleteAliasFinished(index.toString(), name, result));
280+
commandListener.deleteAliasFinished(index.toString(), name, result);
282281
return result;
283282
}
284283

285284
@Override
286285
public String updateSynonym(String synonymGroupId, String... terms) {
287-
commandListener.ifPresent(it -> it.updateSynonymStarted(index.toString(), synonymGroupId, terms));
286+
commandListener.updateSynonymStarted(index.toString(), synonymGroupId, terms);
288287
final String result = search.ftSynUpdate(index.toString(), synonymGroupId, terms);
289-
commandListener.ifPresent(it -> it.updateSynonymFinished(index.toString(), synonymGroupId, terms, result));
288+
commandListener.updateSynonymFinished(index.toString(), synonymGroupId, terms, result);
290289
return result;
291290
}
292291

293292
@Override
294293
public Map<String, List<String>> dumpSynonym() {
295-
commandListener.ifPresent(it -> it.dumpSynonymStarted(index.toString()));
294+
commandListener.dumpSynonymStarted(index.toString());
296295
final Map<String, List<String>> result = search.ftSynDump(index.toString());
297-
commandListener.ifPresent(it -> it.dumpSynonymFinished(index.toString(), result));
296+
commandListener.dumpSynonymFinished(index.toString(), result);
298297
return result;
299298
}
300299

301300
@Override
302301
public Set<String> tagVals(String field) {
303-
commandListener.ifPresent(it -> it.tagValsStarted(index.toString(), field));
302+
commandListener.tagValsStarted(index.toString(), field);
304303
final Set<String> result = search.ftTagVals(index.toString(), field);
305-
commandListener.ifPresent(it -> it.tagValsFinished(index.toString(), field, result));
304+
commandListener.tagValsFinished(index.toString(), field, result);
306305
return result;
307306
}
308307

0 commit comments

Comments
 (0)