/* * Copyright 2018-2019 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 * * https://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 kinesis.webflux; import static org.assertj.core.api.Assumptions.assumeThat; import java.net.Socket; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.function.Supplier; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.cloud.aws.autoconfigure.context.ContextResourceLoaderAutoConfiguration; import org.springframework.cloud.aws.autoconfigure.context.ContextStackAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.integration.metadata.ConcurrentMetadataStore; import org.springframework.integration.metadata.SimpleMetadataStore; import org.springframework.integration.support.locks.DefaultLockRegistry; import org.springframework.integration.support.locks.LockRegistry; import org.springframework.test.web.reactive.server.WebTestClient; import com.amazonaws.ClientConfiguration; import com.amazonaws.SDKGlobalConfiguration; import com.amazonaws.auth.AWSStaticCredentialsProvider; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.client.builder.AwsClientBuilder; import com.amazonaws.regions.Regions; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBAsync; import com.amazonaws.services.kinesis.AmazonKinesisAsync; import com.amazonaws.services.kinesis.AmazonKinesisAsyncClientBuilder; import reactor.core.publisher.Flux; import reactor.test.StepVerifier; /** * @author Artem Bilan */ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = { "spring.cloud.stream.bindings.kinesisSource-out-0.destination = SSE_DATA", "spring.cloud.stream.bindings.kinesisSource-out-0.producer.headerMode = none", "spring.cloud.function.definition=kinesisSink;kinesisSource" } ) @AutoConfigureWebTestClient public class CloudStreamKinesisToWebfluxApplicationTests { @Autowired private WebTestClient webTestClient; @Autowired private KinesisTestConfiguration kinesisTestConfiguration; @BeforeAll static void setup() { boolean isLocalKinesis; try { new Socket("localhost", KinesisTestConfiguration.DEFAULT_KINESALITE_PORT).close(); // Successful connection means local Kinesis is available isLocalKinesis = true; } catch (Exception e) { isLocalKinesis = false; } assumeThat(isLocalKinesis).isTrue(); } @Test void testKinesisToWebFlux() { this.kinesisTestConfiguration.eventQueue.offer("foo"); this.kinesisTestConfiguration.eventQueue.offer("bar"); this.kinesisTestConfiguration.eventQueue.offer("baz"); Flux<String> seeFlux = this.webTestClient.get().uri("/sseFromKinesis") .exchange() .returnResult(String.class) .getResponseBody(); StepVerifier .create(seeFlux) .expectNext("foo", "bar", "baz") .thenCancel() .verify(); } @TestConfiguration @EnableAutoConfiguration(exclude = { ContextResourceLoaderAutoConfiguration.class, ContextStackAutoConfiguration.class }) public static class KinesisTestConfiguration { private static final int DEFAULT_KINESALITE_PORT = 4568; private BlockingQueue<String> eventQueue = new LinkedBlockingQueue<>(); @Bean public Supplier<String> kinesisSource() { return () -> this.eventQueue.poll(); } @Bean public AmazonKinesisAsync amazonKinesis() { // See https://github.com/mhart/kinesalite#cbor-protocol-issues-with-the-java-sdk System.setProperty(SDKGlobalConfiguration.AWS_CBOR_DISABLE_SYSTEM_PROPERTY, "true"); return AmazonKinesisAsyncClientBuilder.standard() .withClientConfiguration( new ClientConfiguration() .withMaxErrorRetry(0) .withConnectionTimeout(1000)) .withEndpointConfiguration( new AwsClientBuilder.EndpointConfiguration("http://localhost:" + DEFAULT_KINESALITE_PORT, Regions.DEFAULT_REGION.getName())) .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("", ""))) .build(); } @Bean public LockRegistry lockRegistry() { return new DefaultLockRegistry(); } @Bean public ConcurrentMetadataStore simpleMetadataStore() { return new SimpleMetadataStore(); } @Bean public AmazonDynamoDBAsync dynamoDB() { return null; } } }