Skip to content

Commit ef738e8

Browse files
committed
Improve Redis module nullability
1 parent c4c7bb9 commit ef738e8

File tree

8 files changed

+40
-55
lines changed

8 files changed

+40
-55
lines changed

spring-integration-redis/src/main/java/org/springframework/integration/redis/inbound/ReactiveRedisStreamMessageProducer.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.time.Duration;
2020
import java.util.function.Function;
2121

22+
import org.jspecify.annotations.Nullable;
2223
import org.reactivestreams.Publisher;
2324
import reactor.core.publisher.Flux;
2425
import reactor.core.publisher.Mono;
@@ -39,7 +40,6 @@
3940
import org.springframework.integration.endpoint.MessageProducerSupport;
4041
import org.springframework.integration.redis.support.RedisHeaders;
4142
import org.springframework.integration.support.AbstractIntegrationMessageBuilder;
42-
import org.jspecify.annotations.Nullable;
4343
import org.springframework.messaging.Message;
4444
import org.springframework.messaging.MessagingException;
4545
import org.springframework.messaging.converter.MessageConversionException;
@@ -136,7 +136,7 @@ public void setAutoAck(boolean autoAck) {
136136
* {@link #createConsumerGroup}. If not set, the defined bean name {@link #getBeanName()} is used.
137137
* @param consumerGroup the Consumer Group on which this adapter should register to listen messages.
138138
*/
139-
public void setConsumerGroup(@Nullable String consumerGroup) {
139+
public void setConsumerGroup(String consumerGroup) {
140140
this.consumerGroup = consumerGroup;
141141
}
142142

@@ -295,8 +295,8 @@ protected void doStart() {
295295
Mono<?> consumerGroupMono = Mono.empty();
296296
if (this.createConsumerGroup) {
297297
consumerGroupMono =
298-
this.reactiveStreamOperations.createGroup(this.streamKey, this.consumerGroup) // NOSONAR
299-
.onErrorReturn(this.consumerGroup);
298+
this.reactiveStreamOperations.createGroup(this.streamKey, this.consumerGroup)
299+
.onErrorReturn(this.consumerGroup);
300300
}
301301

302302
Consumer consumer = Consumer.from(this.consumerGroup, this.consumerName);
@@ -348,8 +348,8 @@ private <T> Publisher<T> handleReceiverError(Throwable error) {
348348
}
349349
}
350350
MessagingException conversionException = (failedMessage != null)
351-
? new MessageConversionException(failedMessage, "Cannot deserialize Redis Stream Record", error)
352-
: new MessageConversionException("Cannot deserialize Redis Stream Record", error);
351+
? new MessageConversionException(failedMessage, "Cannot deserialize Redis Stream Record", error)
352+
: new MessageConversionException("Cannot deserialize Redis Stream Record", error);
353353
if (!sendErrorMessageIfNecessary(null, conversionException)) {
354354
logger.getLog().error(conversionException);
355355
}

spring-integration-redis/src/main/java/org/springframework/integration/redis/inbound/RedisQueueInboundGateway.java

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import java.util.concurrent.Executor;
2020
import java.util.concurrent.TimeUnit;
2121

22+
import org.jspecify.annotations.Nullable;
23+
2224
import org.springframework.beans.factory.BeanClassLoaderAware;
2325
import org.springframework.context.ApplicationEventPublisher;
2426
import org.springframework.context.ApplicationEventPublisherAware;
@@ -37,7 +39,6 @@
3739
import org.springframework.jmx.export.annotation.ManagedMetric;
3840
import org.springframework.jmx.export.annotation.ManagedOperation;
3941
import org.springframework.jmx.export.annotation.ManagedResource;
40-
import org.jspecify.annotations.Nullable;
4142
import org.springframework.messaging.Message;
4243
import org.springframework.messaging.MessagingException;
4344
import org.springframework.scheduling.SchedulingAwareRunnable;
@@ -282,7 +283,7 @@ private Message<Object> prepareRequestMessage(byte[] value) {
282283
}
283284

284285
@SuppressWarnings("unchecked")
285-
private @Nullable byte[] extractReplyPayload(Message<?> replyMessage) {
286+
private byte @Nullable [] extractReplyPayload(Message<?> replyMessage) {
286287
byte[] value = null;
287288
if (!(replyMessage.getPayload() instanceof byte[])) {
288289
if (replyMessage.getPayload() instanceof String && !this.serializerExplicitlySet) {
@@ -324,12 +325,7 @@ private void sleepBeforeRecoveryAttempt() {
324325
}
325326

326327
private void publishException(Exception e) {
327-
if (this.applicationEventPublisher != null) {
328-
this.applicationEventPublisher.publishEvent(new RedisExceptionEvent(this, e));
329-
}
330-
else {
331-
logger.debug(() -> "No application event publisher for exception: " + e.getMessage());
332-
}
328+
this.applicationEventPublisher.publishEvent(new RedisExceptionEvent(this, e));
333329
}
334330

335331
private void restart() {
@@ -355,7 +351,7 @@ public boolean isListening() {
355351
/**
356352
* Returns the size of the Queue specified by {@link #boundListOperations}. The queue is
357353
* represented by a Redis list. If the queue does not exist <code>0</code>
358-
* is returned. See also https://redis.io/commands/llen
354+
* is returned. See also <a href="https://redis.io/commands/llen">LLEN</a>
359355
* @return Size of the queue. Never negative.
360356
*/
361357
@ManagedMetric

spring-integration-redis/src/main/java/org/springframework/integration/redis/inbound/RedisQueueMessageDrivenEndpoint.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.concurrent.TimeUnit;
2222

2323
import org.jspecify.annotations.Nullable;
24+
2425
import org.springframework.beans.factory.BeanClassLoaderAware;
2526
import org.springframework.beans.factory.BeanFactory;
2627
import org.springframework.context.ApplicationEventPublisher;
@@ -195,15 +196,15 @@ public String getComponentType() {
195196

196197
@SuppressWarnings("unchecked")
197198
private void popMessageAndSend() {
198-
@Nullable byte[] value = popForValue();
199+
byte[] value = popForValue();
199200

200201
Message<Object> message = null;
201202

202203
if (value != null) {
203204
if (this.expectMessage) {
204205
try {
205206
if (this.serializer != null) {
206-
message = (Message<Object>) serializer.deserialize(value);
207+
message = (Message<Object>) this.serializer.deserialize(value);
207208
}
208209
}
209210
catch (Exception e) {
@@ -236,8 +237,8 @@ private void popMessageAndSend() {
236237
}
237238
}
238239

239-
private @Nullable byte[] popForValue() {
240-
@Nullable byte[] value = null;
240+
private byte @Nullable [] popForValue() {
241+
byte[] value = null;
241242
try {
242243
if (this.rightPop) {
243244
value = this.boundListOperations.rightPop(this.receiveTimeout, TimeUnit.MILLISECONDS);

spring-integration-redis/src/main/java/org/springframework/integration/redis/metadata/RedisMetadataStore.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.springframework.integration.redis.metadata;
1818

1919
import org.jspecify.annotations.Nullable;
20+
2021
import org.springframework.data.redis.connection.RedisConnectionFactory;
2122
import org.springframework.data.redis.core.BoundHashOperations;
2223
import org.springframework.data.redis.core.RedisOperations;

spring-integration-redis/src/main/java/org/springframework/integration/redis/outbound/ExpressionArgumentsStrategy.java

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
/**
3636
* @author Artem Bilan
3737
* @author Gary Russell
38+
*
3839
* @since 4.0
3940
*/
4041
public class ExpressionArgumentsStrategy implements ArgumentsStrategy, BeanFactoryAware, InitializingBean {
@@ -43,11 +44,11 @@ public class ExpressionArgumentsStrategy implements ArgumentsStrategy, BeanFacto
4344

4445
private final Expression[] argumentExpressions;
4546

47+
private final boolean useCommandVariable;
48+
4649
@SuppressWarnings("NullAway.Init")
4750
private EvaluationContext evaluationContext;
4851

49-
private final boolean useCommandVariable;
50-
5152
@SuppressWarnings("NullAway.Init")
5253
private BeanFactory beanFactory;
5354

@@ -58,28 +59,22 @@ public ExpressionArgumentsStrategy(String[] argumentExpressions) {
5859
public ExpressionArgumentsStrategy(String[] argumentExpressions, boolean useCommandVariable) {
5960
Assert.notNull(argumentExpressions, "'argumentExpressions' must not be null");
6061
Assert.noNullElements(argumentExpressions, "'argumentExpressions' cannot have null values.");
61-
List<Expression> expressions = new LinkedList<Expression>();
62+
List<Expression> expressions = new LinkedList<>();
6263
for (String argumentExpression : argumentExpressions) {
6364
expressions.add(PARSER.parseExpression(argumentExpression));
6465
}
65-
this.argumentExpressions = expressions.toArray(new Expression[expressions.size()]);
66+
this.argumentExpressions = expressions.toArray(new Expression[0]);
6667
this.useCommandVariable = useCommandVariable;
6768
}
6869

69-
public void setIntegrationEvaluationContext(EvaluationContext evaluationContext) {
70-
this.evaluationContext = evaluationContext;
71-
}
72-
7370
@Override
7471
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
7572
this.beanFactory = beanFactory;
7673
}
7774

7875
@Override
7976
public void afterPropertiesSet() {
80-
if (this.evaluationContext == null) {
81-
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(this.beanFactory);
82-
}
77+
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(this.beanFactory);
8378
}
8479

8580
@Override
@@ -90,7 +85,7 @@ public Object[] resolve(String command, Message<?> message) {
9085
evaluationContextToUse = IntegrationContextUtils.getEvaluationContext(this.beanFactory);
9186
evaluationContextToUse.setVariable("cmd", command);
9287
}
93-
List<Object> arguments = new ArrayList<Object>();
88+
List<Object> arguments = new ArrayList<>();
9489
for (Expression argumentExpression : this.argumentExpressions) {
9590
Object argument = argumentExpression.getValue(evaluationContextToUse, message);
9691
if (argument != null) {

spring-integration-redis/src/main/java/org/springframework/integration/redis/outbound/ReactiveRedisStreamMessageHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.util.function.Function;
2020

21+
import org.jspecify.annotations.Nullable;
2122
import reactor.core.publisher.Mono;
2223

2324
import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory;
@@ -33,7 +34,6 @@
3334
import org.springframework.expression.common.LiteralExpression;
3435
import org.springframework.integration.expression.ExpressionUtils;
3536
import org.springframework.integration.handler.AbstractReactiveMessageHandler;
36-
import org.jspecify.annotations.Nullable;
3737
import org.springframework.messaging.Message;
3838
import org.springframework.util.Assert;
3939

spring-integration-redis/src/main/java/org/springframework/integration/redis/outbound/RedisOutboundGateway.java

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.integration.redis.outbound;
1818

19+
import org.jspecify.annotations.Nullable;
20+
1921
import org.springframework.data.redis.connection.RedisConnectionFactory;
2022
import org.springframework.data.redis.core.RedisCallback;
2123
import org.springframework.data.redis.core.RedisTemplate;
@@ -25,9 +27,9 @@
2527
import org.springframework.expression.Expression;
2628
import org.springframework.expression.spel.standard.SpelExpressionParser;
2729
import org.springframework.integration.expression.ExpressionUtils;
30+
import org.springframework.integration.expression.FunctionExpression;
2831
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
2932
import org.springframework.integration.redis.support.RedisHeaders;
30-
import org.jspecify.annotations.Nullable;
3133
import org.springframework.messaging.Message;
3234
import org.springframework.util.Assert;
3335
import org.springframework.util.ObjectUtils;
@@ -50,11 +52,13 @@ public class RedisOutboundGateway extends AbstractReplyProducingMessageHandler {
5052
@SuppressWarnings("NullAway.Init")
5153
private EvaluationContext evaluationContext;
5254

53-
private volatile RedisSerializer<Object> argumentsSerializer = new GenericToStringSerializer<>(Object.class);
55+
private RedisSerializer<Object> argumentsSerializer = new GenericToStringSerializer<>(Object.class);
5456

55-
private volatile Expression commandExpression = PARSER.parseExpression("headers[" + RedisHeaders.COMMAND + "]");
57+
@SuppressWarnings("NullAway") // Cannot see nullability on the generics
58+
private Expression commandExpression =
59+
new FunctionExpression<Message<?>>(message -> message.getHeaders().get(RedisHeaders.COMMAND));
5660

57-
private volatile ArgumentsStrategy argumentsStrategy = new PayloadArgumentsStrategy();
61+
private @Nullable ArgumentsStrategy argumentsStrategy = new PayloadArgumentsStrategy();
5862

5963
public RedisOutboundGateway(RedisTemplate<?, ?> redisTemplate) {
6064
Assert.notNull(redisTemplate, "'redisTemplate' must not be null");
@@ -63,7 +67,7 @@ public RedisOutboundGateway(RedisTemplate<?, ?> redisTemplate) {
6367

6468
public RedisOutboundGateway(RedisConnectionFactory connectionFactory) {
6569
Assert.notNull(connectionFactory, "'connectionFactory' must not be null");
66-
this.redisTemplate = new RedisTemplate<Object, Object>();
70+
this.redisTemplate = new RedisTemplate<>();
6771
this.redisTemplate.setConnectionFactory(connectionFactory);
6872
this.redisTemplate.afterPropertiesSet();
6973
}
@@ -91,14 +95,10 @@ public void setCommandExpressionString(String commandExpression) {
9195
this.commandExpression = EXPRESSION_PARSER.parseExpression(commandExpression);
9296
}
9397

94-
public void setArgumentsStrategy(ArgumentsStrategy argumentsStrategy) {
98+
public void setArgumentsStrategy(@Nullable ArgumentsStrategy argumentsStrategy) {
9599
this.argumentsStrategy = argumentsStrategy;
96100
}
97101

98-
public void setIntegrationEvaluationContext(EvaluationContext evaluationContext) {
99-
this.evaluationContext = evaluationContext;
100-
}
101-
102102
@Override
103103
public String getComponentType() {
104104
return "redis:outbound-gateway";
@@ -107,9 +107,7 @@ public String getComponentType() {
107107
@Override
108108
protected void doInit() {
109109
super.doInit();
110-
if (this.evaluationContext == null) {
111-
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(getBeanFactory());
112-
}
110+
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(getBeanFactory());
113111
}
114112

115113
@Override
@@ -124,22 +122,15 @@ protected void doInit() {
124122

125123
for (int i = 0; i < arguments.length; i++) {
126124
Object argument = arguments[i];
127-
byte[] arg = null;
128-
if (argument instanceof byte[]) {
129-
arg = (byte[]) argument;
130-
}
131-
else {
132-
arg = this.argumentsSerializer.serialize(argument);
133-
}
134-
args[i] = arg;
125+
args[i] = argument instanceof byte[] bytes ? bytes : this.argumentsSerializer.serialize(argument);
135126
}
136127
}
137128
}
138129

139130
final byte[][] actualArgs = args != null ? args : EMPTY_ARGS;
140131

141132
return this.redisTemplate.execute(
142-
(RedisCallback<Object>) connection -> connection.execute(command, actualArgs));
133+
(RedisCallback<@Nullable Object>) connection -> connection.execute(command, actualArgs));
143134
}
144135

145136
private static class PayloadArgumentsStrategy implements ArgumentsStrategy {

spring-integration-redis/src/main/java/org/springframework/integration/redis/outbound/RedisQueueOutboundGateway.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,15 @@
1818

1919
import java.util.concurrent.TimeUnit;
2020

21+
import org.jspecify.annotations.Nullable;
22+
2123
import org.springframework.data.redis.connection.RedisConnectionFactory;
2224
import org.springframework.data.redis.core.BoundListOperations;
2325
import org.springframework.data.redis.core.RedisTemplate;
2426
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
2527
import org.springframework.data.redis.serializer.RedisSerializer;
2628
import org.springframework.data.redis.serializer.StringRedisSerializer;
2729
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
28-
import org.jspecify.annotations.Nullable;
2930
import org.springframework.messaging.Message;
3031
import org.springframework.util.AlternativeJdkIdGenerator;
3132
import org.springframework.util.Assert;

0 commit comments

Comments
 (0)