diff --git a/pom.xml b/pom.xml
index 5c9636c3d..cbea20479 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,9 +30,10 @@
spring-cloud-stream-rxjava
spring-cloud-stream-samples
spring-cloud-stream-module-launcher
- docs
spring-cloud-stream-test-support
+ spring-cloud-stream-test-support-internal
spring-cloud-stream-configuration-metadata
+ docs
@@ -118,6 +119,16 @@
spring-cloud-stream-test-support
1.0.0.BUILD-SNAPSHOT
+
+ org.springframework.cloud
+ spring-cloud-stream-test-support-internal
+ ${project.version}
+
+
+ org.springframework.cloud
+ spring-cloud-stream-module-test-support
+ ${project.version}
+
org.springframework.integration
spring-integration-core
diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/pom.xml b/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/pom.xml
index eb2f0eb31..5292af0d4 100644
--- a/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/pom.xml
+++ b/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/pom.xml
@@ -14,7 +14,6 @@
- UTF-8
0.8.2.1
1.2.0.RELEASE
1.0.0
@@ -44,6 +43,11 @@
spring-cloud-stream-binder-test
test
+
+ org.springframework.cloud
+ spring-cloud-stream-test-support-internal
+ test
+
org.springframework.integration
spring-integration-kafka
diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/KafkaBinderTests.java b/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/KafkaBinderTests.java
index 3e40080b7..29327a06c 100644
--- a/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/KafkaBinderTests.java
+++ b/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/KafkaBinderTests.java
@@ -36,6 +36,7 @@ import org.junit.Ignore;
import org.junit.Test;
import org.springframework.cloud.stream.binder.PartitionCapableBinderTests;
+import org.springframework.cloud.stream.test.junit.kafka.KafkaTestSupport;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.kafka.core.KafkaMessage;
diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/KafkaTestBinder.java b/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/KafkaTestBinder.java
index 4939c6159..9f46d337d 100644
--- a/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/KafkaTestBinder.java
+++ b/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/KafkaTestBinder.java
@@ -22,6 +22,8 @@ import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Registration;
import org.springframework.cloud.stream.binder.AbstractTestBinder;
+import org.springframework.cloud.stream.test.junit.kafka.KafkaTestSupport;
+import org.springframework.cloud.stream.test.junit.kafka.TestKafkaCluster;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.integration.codec.Codec;
import org.springframework.integration.codec.kryo.KryoRegistrar;
diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/pom.xml b/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/pom.xml
index f84b607e4..615056ab2 100644
--- a/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/pom.xml
+++ b/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/pom.xml
@@ -46,6 +46,11 @@
spring-cloud-stream-binder-test
test
+
+ org.springframework.cloud
+ spring-cloud-stream-test-support-internal
+ test
+
org.springframework.boot
spring-boot-starter-amqp
diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/LocalizedQueueConnectionFactoryIntegrationTests.java b/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/LocalizedQueueConnectionFactoryIntegrationTests.java
index 5dcd55d6a..2548e07b4 100644
--- a/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/LocalizedQueueConnectionFactoryIntegrationTests.java
+++ b/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/LocalizedQueueConnectionFactoryIntegrationTests.java
@@ -29,6 +29,7 @@ import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.cloud.stream.test.junit.rabbit.RabbitTestSupport;
/**
diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitAdminTestSupport.java b/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitAdminTestSupport.java
deleted file mode 100644
index 776ac835e..000000000
--- a/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitAdminTestSupport.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2015 the original author or authors.
- *
- * 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 org.springframework.cloud.stream.binder.rabbit;
-
-
-import org.springframework.http.HttpStatus;
-import org.springframework.web.client.HttpClientErrorException;
-import org.springframework.web.client.RestTemplate;
-import org.springframework.cloud.stream.binder.AbstractExternalResourceTestSupport;
-
-import java.util.Map;
-
-/**
- * JUnit {@link org.junit.Rule} that detects the fact that RabbitMQ is available on localhost with
- * the management plugin enabled.
- *
- * @author Gary Russell
- * @since 1.2
- */
-public class RabbitAdminTestSupport extends AbstractExternalResourceTestSupport {
-
- public RabbitAdminTestSupport() {
- super("RABBITADMIN");
- }
-
- @Override
- protected void obtainResource() throws Exception {
- resource = new RestTemplate();
- try {
- resource.getForObject("http://localhost:15672/api/overview", Map.class);
- }
- catch (HttpClientErrorException e) {
- if (e.getStatusCode() != HttpStatus.UNAUTHORIZED) {
- throw e;
- }
- }
- }
-
- @Override
- protected void cleanupResource() throws Exception {
- }
-
-}
diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitBinderCleanerTests.java b/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitBinderCleanerTests.java
index 3b9164b57..bf61401d2 100644
--- a/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitBinderCleanerTests.java
+++ b/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitBinderCleanerTests.java
@@ -35,6 +35,7 @@ import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.core.ChannelCallback;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.cloud.stream.test.junit.rabbit.RabbitTestSupport;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.cloud.stream.binder.BinderUtils;
@@ -57,10 +58,7 @@ public class RabbitBinderCleanerTests {
private static final String BINDER_PREFIX = "binder.rabbit.";
@Rule
- public RabbitAdminTestSupport adminTest = new RabbitAdminTestSupport();
-
- @Rule
- public RabbitTestSupport test = new RabbitTestSupport();
+ public RabbitTestSupport rabbitWithMgmtEnabled = new RabbitTestSupport(true);
@Test
public void testCleanStream() {
@@ -93,7 +91,7 @@ public class RabbitBinderCleanerTests {
.buildAndExpand("/", MessageChannelBinderSupport.constructDLQName(queue1Name)).encode().toUri();
template.put(uri, new AmqpQueue(false, true));
}
- CachingConnectionFactory connectionFactory = test.getResource();
+ CachingConnectionFactory connectionFactory = rabbitWithMgmtEnabled.getResource();
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
final FanoutExchange fanout1 = new FanoutExchange(
MessageChannelBinderSupport.applyPrefix(BINDER_PREFIX, MessageChannelBinderSupport.applyPubSub(
diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitBinderTests.java b/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitBinderTests.java
index 66afadc96..f39056a09 100644
--- a/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitBinderTests.java
+++ b/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitBinderTests.java
@@ -46,6 +46,7 @@ import org.springframework.cloud.stream.binder.BinderProperties;
import org.springframework.cloud.stream.binder.Binding;
import org.springframework.cloud.stream.binder.PartitionCapableBinderTests;
import org.springframework.cloud.stream.binder.Spy;
+import org.springframework.cloud.stream.test.junit.rabbit.RabbitTestSupport;
import org.springframework.expression.spel.standard.SpelExpression;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.QueueChannel;
diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/pom.xml b/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/pom.xml
index c2e8f5642..1e16457e1 100644
--- a/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/pom.xml
+++ b/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/pom.xml
@@ -46,6 +46,11 @@
spring-cloud-stream-binder-test
test
+
+ org.springframework.cloud
+ spring-cloud-stream-test-support-internal
+ test
+
org.springframework.boot
spring-boot-starter-redis
diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisBinderTests.java b/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisBinderTests.java
index ac16192d1..6f0008cd4 100644
--- a/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisBinderTests.java
+++ b/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisBinderTests.java
@@ -38,6 +38,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.springframework.cloud.stream.binder.PartitionCapableBinderTests;
+import org.springframework.cloud.stream.test.junit.redis.RedisTestSupport;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisPublishingMessageHandlerTests.java b/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisPublishingMessageHandlerTests.java
index ea0f3c367..898918522 100644
--- a/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisPublishingMessageHandlerTests.java
+++ b/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisPublishingMessageHandlerTests.java
@@ -27,6 +27,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.springframework.cloud.stream.binder.BinderTestUtils;
+import org.springframework.cloud.stream.test.junit.redis.RedisTestSupport;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisQueueInboundChannelAdapterTests.java b/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisQueueInboundChannelAdapterTests.java
index 766fd487f..e740d5a2d 100644
--- a/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisQueueInboundChannelAdapterTests.java
+++ b/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisQueueInboundChannelAdapterTests.java
@@ -31,6 +31,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.springframework.cloud.stream.binder.BinderTestUtils;
+import org.springframework.cloud.stream.test.junit.redis.RedisTestSupport;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericToStringSerializer;
diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisQueueOutboundChannelAdapterTests.java b/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisQueueOutboundChannelAdapterTests.java
index 1be1de96d..f43402561 100644
--- a/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisQueueOutboundChannelAdapterTests.java
+++ b/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisQueueOutboundChannelAdapterTests.java
@@ -27,6 +27,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.springframework.cloud.stream.binder.BinderTestUtils;
+import org.springframework.cloud.stream.test.junit.redis.RedisTestSupport;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-test/src/main/java/org/springframework/cloud/stream/binder/AbstractExternalResourceTestSupport.java b/spring-cloud-stream-binders/spring-cloud-stream-binder-test/src/main/java/org/springframework/cloud/stream/binder/AbstractExternalResourceTestSupport.java
deleted file mode 100644
index b8f811b56..000000000
--- a/spring-cloud-stream-binders/spring-cloud-stream-binder-test/src/main/java/org/springframework/cloud/stream/binder/AbstractExternalResourceTestSupport.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright 2013 the original author or authors.
- *
- * 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 org.springframework.cloud.stream.binder;
-
-import static org.junit.Assert.fail;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.junit.Assume;
-import org.junit.Rule;
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
-import org.springframework.util.Assert;
-
-
-/**
- * Abstract base class for JUnit {@link Rule}s that detect the presence of some external resource. If the resource is
- * indeed present, it will be available during the test lifecycle through {@link #getResource()}. If it is not, tests
- * will either fail or be skipped, depending on the value of system property {@value #XD_EXTERNAL_SERVERS_REQUIRED}.
- *
- * @author Eric Bottard
- * @author Gary Russell
- */
-public abstract class AbstractExternalResourceTestSupport implements TestRule {
-
- public static final String XD_EXTERNAL_SERVERS_REQUIRED = "XD_EXTERNAL_SERVERS_REQUIRED";
-
- protected R resource;
-
- private String resourceDescription;
-
- protected final Logger logger = LoggerFactory.getLogger(this.getClass());
-
- protected AbstractExternalResourceTestSupport(String resourceDescription) {
- Assert.hasText(resourceDescription, "resourceDescription is required");
- this.resourceDescription = resourceDescription;
- }
-
- @Override
- public Statement apply(final Statement base, Description description) {
- try {
- obtainResource();
- }
- catch (Exception e) {
- maybeCleanup();
-
- return failOrSkip(e);
- }
-
- return new Statement() {
-
- @Override
- public void evaluate() throws Throwable {
- try {
- base.evaluate();
- }
- finally {
- try {
- cleanupResource();
- }
- catch (Exception ignored) {
- logger.warn("Exception while trying to cleanup proper resource", ignored);
- }
- }
- }
-
- };
- }
-
- private Statement failOrSkip(final Exception e) {
- String serversRequired = System.getenv(XD_EXTERNAL_SERVERS_REQUIRED);
- if ("true".equalsIgnoreCase(serversRequired)) {
- logger.error(resourceDescription + " IS REQUIRED BUT NOT AVAILABLE", e);
- fail(resourceDescription + " IS NOT AVAILABLE");
- // Never reached, here to satisfy method signature
- return null;
- }
- else {
- logger.error(resourceDescription + " IS NOT AVAILABLE, SKIPPING TESTS", e);
- return new Statement() {
-
- @Override
- public void evaluate() throws Throwable {
- Assume.assumeTrue("Skipping test due to " + resourceDescription + " not being available " + e, false);
- }
- };
- }
- }
-
- private void maybeCleanup() {
- if (resource != null) {
- try {
- cleanupResource();
- }
- catch (Exception ignored) {
- logger.warn("Exception while trying to cleanup failed resource", ignored);
- }
- }
- }
-
- public R getResource() {
- return resource;
- }
-
- /**
- * Perform cleanup of the {@link #resource} field, which is guaranteed to be non null.
- *
- * @throws Exception any exception thrown by this method will be logged and swallowed
- */
- protected abstract void cleanupResource() throws Exception;
-
- /**
- * Try to obtain and validate a resource. Implementors should either set the {@link #resource} field with a valid
- * resource and return normally, or throw an exception.
- */
- protected abstract void obtainResource() throws Exception;
-
-}
diff --git a/spring-cloud-stream-test-support-internal/pom.xml b/spring-cloud-stream-test-support-internal/pom.xml
new file mode 100644
index 000000000..a5d81bb37
--- /dev/null
+++ b/spring-cloud-stream-test-support-internal/pom.xml
@@ -0,0 +1,74 @@
+
+
+ 4.0.0
+
+ org.springframework.cloud
+ spring-cloud-stream-parent
+ 1.0.0.BUILD-SNAPSHOT
+
+ spring-cloud-stream-test-support-internal
+ Set of classes and utility code that may assist in testing both
+ spring-cloud-stream itself, and also modules.
+
+ 0.8.2.1
+ 2.6.0
+
+
+
+ junit
+ junit
+ compile
+
+
+ org.springframework.boot
+ spring-boot-starter-logging
+
+
+ org.springframework
+ spring-core
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-redis
+ true
+
+
+
+ org.apache.curator
+ curator-recipes
+ ${curator.version}
+ true
+
+
+ org.apache.kafka
+ kafka_2.10
+ ${kafka.version}
+ true
+
+
+ org.apache.kafka
+ kafka_2.10
+ test
+ ${kafka.version}
+ true
+
+
+ org.apache.curator
+ curator-test
+ ${curator.version}
+ true
+
+
+
+ org.springframework.boot
+ spring-boot-starter-amqp
+ true
+
+
+
+
diff --git a/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/AbstractExternalResourceTestSupport.java b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/AbstractExternalResourceTestSupport.java
new file mode 100644
index 000000000..2379397c6
--- /dev/null
+++ b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/AbstractExternalResourceTestSupport.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2015 the original author or authors.
+ *
+ * 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 org.springframework.cloud.stream.test.junit;
+
+import static org.junit.Assert.fail;
+
+import org.junit.Assume;
+import org.junit.Rule;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.util.Assert;
+
+/**
+ * Abstract base class for JUnit {@link Rule}s that detect the presence of some external resource. If the resource is
+ * indeed present, it will be available during the test lifecycle through {@link #getResource()}. If it is not, tests
+ * will either fail or be skipped, depending on the value of system property {@value #SCS_EXTERNAL_SERVERS_REQUIRED}.
+ *
+ * @author Eric Bottard
+ * @author Gary Russell
+ */
+public abstract class AbstractExternalResourceTestSupport implements TestRule {
+
+ public static final String SCS_EXTERNAL_SERVERS_REQUIRED = "SCS_EXTERNAL_SERVERS_REQUIRED";
+
+ protected R resource;
+
+ private String resourceDescription;
+
+ protected final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ protected AbstractExternalResourceTestSupport(String resourceDescription) {
+ Assert.hasText(resourceDescription, "resourceDescription is required");
+ this.resourceDescription = resourceDescription;
+ }
+
+ @Override
+ public Statement apply(final Statement base, Description description) {
+ try {
+ obtainResource();
+ }
+ catch (Exception e) {
+ maybeCleanup();
+
+ return failOrSkip(e);
+ }
+
+ return new Statement() {
+
+ @Override
+ public void evaluate() throws Throwable {
+ try {
+ base.evaluate();
+ }
+ finally {
+ try {
+ cleanupResource();
+ }
+ catch (Exception ignored) {
+ logger.warn("Exception while trying to cleanup proper resource", ignored);
+ }
+ }
+ }
+
+ };
+ }
+
+ private Statement failOrSkip(final Exception e) {
+ String serversRequired = System.getenv(SCS_EXTERNAL_SERVERS_REQUIRED);
+ if ("true".equalsIgnoreCase(serversRequired)) {
+ logger.error(resourceDescription + " IS REQUIRED BUT NOT AVAILABLE", e);
+ fail(resourceDescription + " IS NOT AVAILABLE");
+ // Never reached, here to satisfy method signature
+ return null;
+ }
+ else {
+ logger.error(resourceDescription + " IS NOT AVAILABLE, SKIPPING TESTS", e);
+ return new Statement() {
+
+ @Override
+ public void evaluate() throws Throwable {
+ Assume.assumeTrue("Skipping test due to " + resourceDescription + " not being available " + e, false);
+ }
+ };
+ }
+ }
+
+ private void maybeCleanup() {
+ if (resource != null) {
+ try {
+ cleanupResource();
+ }
+ catch (Exception ignored) {
+ logger.warn("Exception while trying to cleanup failed resource", ignored);
+ }
+ }
+ }
+
+ public R getResource() {
+ return resource;
+ }
+
+ /**
+ * Perform cleanup of the {@link #resource} field, which is guaranteed to be non null.
+ *
+ * @throws Exception any exception thrown by this method will be logged and swallowed
+ */
+ protected abstract void cleanupResource() throws Exception;
+
+ /**
+ * Try to obtain and validate a resource. Implementors should either set the {@link #resource} field with a valid
+ * resource and return normally, or throw an exception.
+ */
+ protected abstract void obtainResource() throws Exception;
+
+}
diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/EmbeddedZookeeper.java b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/kafka/EmbeddedZookeeper.java
similarity index 97%
rename from spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/EmbeddedZookeeper.java
rename to spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/kafka/EmbeddedZookeeper.java
index 907986982..78778d1cf 100644
--- a/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/EmbeddedZookeeper.java
+++ b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/kafka/EmbeddedZookeeper.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package org.springframework.cloud.stream.binder.kafka;
+package org.springframework.cloud.stream.test.junit.kafka;
import java.io.File;
import java.net.InetSocketAddress;
diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/KafkaTestSupport.java b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/kafka/KafkaTestSupport.java
similarity index 97%
rename from spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/KafkaTestSupport.java
rename to spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/kafka/KafkaTestSupport.java
index 6dafd8a0d..ba26b9901 100644
--- a/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/KafkaTestSupport.java
+++ b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/kafka/KafkaTestSupport.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package org.springframework.cloud.stream.binder.kafka;
+package org.springframework.cloud.stream.test.junit.kafka;
import java.util.Properties;
@@ -34,7 +34,8 @@ import org.junit.Rule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.cloud.stream.binder.AbstractExternalResourceTestSupport;
+import org.springframework.cloud.stream.test.junit.AbstractExternalResourceTestSupport;
+
/**
* JUnit {@link Rule} that starts an embedded Kafka server (with an associated Zookeeper)
diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/TestKafkaCluster.java b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/kafka/TestKafkaCluster.java
similarity index 52%
rename from spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/TestKafkaCluster.java
rename to spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/kafka/TestKafkaCluster.java
index 6a609aab3..e96598f0d 100644
--- a/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/TestKafkaCluster.java
+++ b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/kafka/TestKafkaCluster.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package org.springframework.cloud.stream.binder.kafka;
+package org.springframework.cloud.stream.test.junit.kafka;
import kafka.admin.AdminUtils;
import kafka.consumer.Consumer;
@@ -85,87 +85,9 @@ public class TestKafkaCluster {
}
- /**
- * See XD-2293. This is used to reproduce Kafka rebalance issues.
- */
- public static void main(String[] args) throws Exception {
- TestKafkaCluster cluster = new TestKafkaCluster();
- ZkClient client = new ZkClient(cluster.getZkConnectString(), 10000, 10000, KafkaMessageChannelBinder.utf8Serializer);
- int partitions = 5;
- int replication = 1;
- AdminUtils.createTopic(client, "mytopic", partitions, replication, new Properties());
-
- Properties props = new Properties();
- props.put("zookeeper.connect", cluster.getZkConnectString());
- props.put("group.id", "foo");
- props.put("rebalance.backoff.ms", "2000");
- props.put("rebalance.max.retries", "2000");
- ConsumerConfig config = new ConsumerConfig(props);
-
-
- CuratorFramework curator = CuratorFrameworkFactory.newClient(cluster.getZkConnectString(), new RetryUntilElapsed(1000, 100));
- curator.start();
-
- RebalanceListener listener = null;
- for (int i = 0; i < 5; i++) {
- System.out.format("%nCreating consumer #%d%n", i + 1);
- ConsumerConnector connector = Consumer.createJavaConsumerConnector(config);
- connector.createMessageStreams(Collections.singletonMap("mytopic", 1));
- if (i == 0) {
- PathChildrenCache cache = new PathChildrenCache(curator, "/consumers/foo/owners/mytopic", true);
- listener = new RebalanceListener(5);
- cache.getListenable().addListener(listener);
- cache.start(PathChildrenCache.StartMode.POST_INITIALIZED_EVENT);
- }
-
- synchronized (listener) {
- System.out.println("******** Waiting for rebalance...");
- listener.wait();
- }
-
- }
-
- System.out.println();
-
- }
public String getZkConnectString() {
return zkServer.getConnectString();
}
- private static class RebalanceListener implements PathChildrenCacheListener {
-
- private int expected;
-
- private int actual;
-
- private boolean ready;
-
- public RebalanceListener(int expected) {
- this.expected = expected;
- }
-
- @Override
- public synchronized void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
- System.out.println(event);
- System.out.println(event.getData() != null ? new String(event.getData().getData()) : "no data");
- switch (event.getType()) {
- case CHILD_ADDED:
- actual++;
- if (ready && actual == expected) {
- System.out.println("*** Moving on... ");
- this.notify();
- }
- break;
- case CHILD_REMOVED:
- actual--;
- break;
- case INITIALIZED:
- Assert.isTrue(actual == expected);
- ready = true;
- this.notify();
- break;
- }
- }
- }
}
diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitTestSupport.java b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/rabbit/RabbitTestSupport.java
similarity index 88%
rename from spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitTestSupport.java
rename to spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/rabbit/RabbitTestSupport.java
index fc27def0c..84f597dc1 100644
--- a/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitTestSupport.java
+++ b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/rabbit/RabbitTestSupport.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2015 the original author or authors.
+ * Copyright 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,14 +14,14 @@
* limitations under the License.
*/
-package org.springframework.cloud.stream.binder.rabbit;
+package org.springframework.cloud.stream.test.junit.rabbit;
-
-import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
-import org.springframework.cloud.stream.binder.AbstractExternalResourceTestSupport;
+import java.net.Socket;
import javax.net.SocketFactory;
-import java.net.Socket;
+
+import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
+import org.springframework.cloud.stream.test.junit.AbstractExternalResourceTestSupport;
/**
* JUnit {@link org.junit.Rule} that detects the fact that RabbitMQ is available on localhost.
diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisTestSupport.java b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/redis/RedisTestSupport.java
similarity index 78%
rename from spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisTestSupport.java
rename to spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/redis/RedisTestSupport.java
index 4db9c8ca7..8aeab0245 100644
--- a/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisTestSupport.java
+++ b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/redis/RedisTestSupport.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,15 +14,13 @@
* limitations under the License.
*/
-package org.springframework.cloud.stream.binder.redis;
-
-import org.junit.Rule;
+package org.springframework.cloud.stream.test.junit.redis;
+import org.springframework.cloud.stream.test.junit.AbstractExternalResourceTestSupport;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
-import org.springframework.cloud.stream.binder.AbstractExternalResourceTestSupport;
/**
- * JUnit {@link Rule} that detects the fact that a Redis server is running on localhost.
+ * JUnit {@link org.junit.Rule} that detects the fact that a Redis server is running on localhost.
*
* @author Gary Russell
* @author Eric Bottard
diff --git a/spring-cloud-stream-test-support/pom.xml b/spring-cloud-stream-test-support/pom.xml
index d94053bd0..49266d3ee 100644
--- a/spring-cloud-stream-test-support/pom.xml
+++ b/spring-cloud-stream-test-support/pom.xml
@@ -6,12 +6,8 @@
spring-cloud-stream-parent
1.0.0.BUILD-SNAPSHOT
- org.springframework.cloud
- spring-cloud-stream-test-support
- Spring Cloud Stream Test Support
-
- UTF-8
-
+ spring-cloud-stream-module-test-support
+ A set of classes to ease testing of Spring Cloud Stream modules.
org.springframework.boot