Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/**
* JUnit Jupiter conditions.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.integration.test.condition;
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package org.springframework.integration.test.context;

import java.util.Objects;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;

Expand Down Expand Up @@ -54,7 +56,7 @@ static void beforeAll() {
TEST_INTEGRATION_CONTEXT.refresh();
}
catch (IllegalStateException ex) {
if (!ex.getMessage().contains("just call 'refresh' once")) {
if (!Objects.requireNonNull(ex.getMessage()).contains("just call 'refresh' once")) {
throw ex;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/**
* Test context support classes.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.integration.test.context;

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.jspecify.annotations.Nullable;

import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
Expand Down Expand Up @@ -56,13 +57,13 @@ public final class PayloadAndHeaderMatcher<T> extends BaseMatcher<Message<?>> {

private final Map<String, Object> headers;

private final String[] ignoreKeys;
private final String @Nullable [] ignoreKeys;

public static <P> PayloadAndHeaderMatcher<P> sameExceptIgnorableHeaders(Message<P> expected, String... ignoreKeys) {
return new PayloadAndHeaderMatcher<>(expected, ignoreKeys);
}

private PayloadAndHeaderMatcher(Message<T> expected, String... ignoreKeys) {
private PayloadAndHeaderMatcher(Message<T> expected, String @Nullable ... ignoreKeys) {
this.ignoreKeys = ignoreKeys != null ? Arrays.copyOf(ignoreKeys, ignoreKeys.length) : null;
this.payload = expected.getPayload();
this.headers = extractHeadersToAssert(expected);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/**
* Provides several {@link org.hamcrest.BaseMatcher} implementations.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.integration.test.matcher;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/**
* AssertJ predicates.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.integration.test.predicate;
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.springframework.integration.test.support;

import java.util.List;
import java.util.Objects;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -54,14 +55,15 @@
@DirtiesContext
public abstract class AbstractRequestResponseScenarioTest {

private List<RequestResponseScenario> scenarios = null;
@SuppressWarnings("NullAway.Init")
private List<RequestResponseScenario> scenarios;

@Autowired
private ApplicationContext applicationContext;

@BeforeEach
public void setUp() {
scenarios = defineRequestResponseScenarios();
this.scenarios = defineRequestResponseScenarios();
}

/**
Expand All @@ -79,8 +81,9 @@ public void testRequestResponseScenarios() {
MessageChannel.class);
MessageChannel outputChannel = applicationContext.getBean(scenario.getOutputChannelName(),
MessageChannel.class);
if (outputChannel instanceof SubscribableChannel) {
((SubscribableChannel) outputChannel).subscribe(scenario.getResponseValidator());
AbstractResponseValidator<?> responseValidator = scenario.getResponseValidator();
if (outputChannel instanceof SubscribableChannel subscribableChannel) {
subscribableChannel.subscribe(responseValidator);
}

assertThat(inputChannel.send(scenario.getMessage()))
Expand All @@ -89,14 +92,14 @@ public void testRequestResponseScenarios() {
if (outputChannel instanceof PollableChannel) {
Message<?> response = ((PollableChannel) outputChannel).receive(10000); // NOSONAR magic number
assertThat(response).as(name + ": receive timeout on " + scenario.getOutputChannelName()).isNotNull();
scenario.getResponseValidator().handleMessage(response);
responseValidator.handleMessage(Objects.requireNonNull(response));
}

assertThat(scenario.getResponseValidator().getLastMessage())
assertThat(responseValidator.getLastMessage())
.as("message was not handled on " + outputChannel + " for scenario '" + name + "'.").isNotNull();

if (outputChannel instanceof SubscribableChannel) {
((SubscribableChannel) outputChannel).unsubscribe(scenario.getResponseValidator());
((SubscribableChannel) outputChannel).unsubscribe(responseValidator);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.springframework.integration.test.support;

import java.util.List;
import java.util.Objects;

import org.junit.Before;
import org.junit.Test;
Expand Down Expand Up @@ -56,14 +57,15 @@
@Deprecated(since = "7.0", forRemoval = true)
public abstract class AbstractRequestResponseScenarioTests {

private List<RequestResponseScenario> scenarios = null;
@SuppressWarnings("NullAway.Init")
private List<RequestResponseScenario> scenarios;

@Autowired
private ApplicationContext applicationContext;

@Before
public void setUp() {
scenarios = defineRequestResponseScenarios();
this.scenarios = defineRequestResponseScenarios();
}

/**
Expand Down Expand Up @@ -91,7 +93,7 @@ public void testRequestResponseScenarios() {
if (outputChannel instanceof PollableChannel) {
Message<?> response = ((PollableChannel) outputChannel).receive(10000); // NOSONAR magic number
assertThat(response).as(name + ": receive timeout on " + scenario.getOutputChannelName()).isNotNull();
scenario.getResponseValidator().handleMessage(response);
scenario.getResponseValidator().handleMessage(Objects.requireNonNull(response));
}

assertThat(scenario.getResponseValidator().getLastMessage())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,22 @@

package org.springframework.integration.test.support;

import org.jspecify.annotations.Nullable;

import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;

/**
* The base class for response validators used for {@link RequestResponseScenario}s
*
* @author David Turanski
* @author Artem Bilan
*
*/
public abstract class AbstractResponseValidator<T> implements MessageHandler {

private Message<?> lastMessage;
private @Nullable Message<?> lastMessage;

/**
* handle the message
Expand All @@ -39,6 +43,13 @@ public void handleMessage(Message<?> message) throws MessagingException {
validateResponse((T) (extractPayload() ? message.getPayload() : message));
}

/**
* @return the lastMessage
*/
public @Nullable Message<?> getLastMessage() {
return this.lastMessage;
}

/**
* Implement this method to validate the response (Message or Payload)
* @param response The response.
Expand All @@ -51,11 +62,4 @@ public void handleMessage(Message<?> message) throws MessagingException {
*/
protected abstract boolean extractPayload();

/**
* @return the lastMessage
*/
public Message<?> getLastMessage() {
return lastMessage;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,20 @@

package org.springframework.integration.test.support;

import java.util.Objects;

import org.jspecify.annotations.Nullable;

import org.springframework.messaging.Message;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.util.Assert;

/**
* Defines a Spring Integration request response test scenario. All setter methods may
* be chained.
*
* @author David Turanski
* @author Artem Bilan
*
*/
public class RequestResponseScenario {
Expand All @@ -32,20 +38,21 @@ public class RequestResponseScenario {

private final String outputChannelName;

private Object payload;
private @Nullable Object payload;

private Message<?> message;
private @Nullable Message<?> message;

@SuppressWarnings("NullAway.Init")
private AbstractResponseValidator<?> responseValidator;

private String name;
private @Nullable String name;

protected Message<? extends Object> getMessage() {
if (message == null) {
return new GenericMessage<Object>(this.payload);
protected Message<?> getMessage() {
if (this.message == null) {
return new GenericMessage<>(Objects.requireNonNull(this.payload));
}
else {
return message;
return this.message;
}
}

Expand All @@ -64,23 +71,23 @@ public RequestResponseScenario(String inputChannelName, String outputChannelName
* @return the input channel name
*/
public String getInputChannelName() {
return inputChannelName;
return this.inputChannelName;
}

/**
*
* @return the output channel name
*/
public String getOutputChannelName() {
return outputChannelName;
return this.outputChannelName;
}

/**
*
* @return the request message payload
*/
public Object getPayload() {
return payload;
public @Nullable Object getPayload() {
return this.payload;
}

/**
Expand All @@ -97,8 +104,8 @@ public RequestResponseScenario setPayload(Object payload) {
*
* @return the scenario name
*/
public String getName() {
return name;
public @Nullable String getName() {
return this.name;
}

/**
Expand All @@ -117,7 +124,7 @@ public RequestResponseScenario setName(String name) {
* @see AbstractResponseValidator
*/
public AbstractResponseValidator<?> getResponseValidator() {
return responseValidator;
return this.responseValidator;
}

/**
Expand All @@ -142,7 +149,10 @@ public RequestResponseScenario setMessage(Message<?> message) {
}

protected void init() {
Assert.state(message == null || payload == null, "cannot set both message and payload");
Assert.state(this.message == null || this.payload == null, "cannot set both message and payload");
Assert.state(this.responseValidator != null,
"A 'responseValidator' must be provided for the 'SubscribableChannel' scenario.");

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
* Provides several test support classes including for testing Spring Integration
* request-response message scenarios.
*/
@org.jspecify.annotations.NullMarked
package org.springframework.integration.test.support;
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

import org.jspecify.annotations.Nullable;

import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;

Expand Down Expand Up @@ -52,7 +54,7 @@ public OnlyOnceTrigger() {
}

@Override
public Instant nextExecution(TriggerContext triggerContext) {
public @Nullable Instant nextExecution(TriggerContext triggerContext) {
if (this.hasRun.getAndSet(true)) {
this.latch.countDown();
return null;
Expand All @@ -61,6 +63,23 @@ public Instant nextExecution(TriggerContext triggerContext) {
return this.executionTime;
}

public void reset() {
this.latch = new CountDownLatch(1);
this.hasRun.set(false);
}

public void await() {
try {
if (!this.latch.await(10000, TimeUnit.MILLISECONDS)) { // NOSONAR magic number
throw new IllegalStateException("test latch.await() did not count down");
}
}
catch (InterruptedException ex) {
Thread.currentThread().interrupt();
throw new IllegalStateException("test latch.await() interrupted", ex);
}
}

@Override
public int hashCode() {
final int prime = 31;
Expand All @@ -84,21 +103,4 @@ public boolean equals(Object obj) {
return this.executionTime.equals(other.executionTime);
}

public void reset() {
this.latch = new CountDownLatch(1);
this.hasRun.set(false);
}

public void await() {
try {
if (!this.latch.await(10000, TimeUnit.MILLISECONDS)) { // NOSONAR magic number
throw new IllegalStateException("test latch.await() did not count down");
}
}
catch (InterruptedException ex) {
Thread.currentThread().interrupt();
throw new IllegalStateException("test latch.await() interrupted", ex);
}
}

}
Loading