Search in sources :

Example 6 with PutRecordsRequestEntry

use of com.amazonaws.services.kinesis.model.PutRecordsRequestEntry in project spring-integration-aws by spring-projects.

the class KinesisMessageHandlerTests method testKinesisMessageHandler.

@Test
@SuppressWarnings("unchecked")
public void testKinesisMessageHandler() throws Exception {
    Message<?> message = MessageBuilder.withPayload("message").build();
    try {
        this.kinesisSendChannel.send(message);
    } catch (Exception e) {
        assertThat(e).isInstanceOf(MessageHandlingException.class);
        assertThat(e.getCause()).isInstanceOf(IllegalStateException.class);
        assertThat(e.getMessage()).contains("'stream' must not be null for sending a Kinesis record");
    }
    this.kinesisMessageHandler.setStream("foo");
    try {
        this.kinesisSendChannel.send(message);
    } catch (Exception e) {
        assertThat(e).isInstanceOf(MessageHandlingException.class);
        assertThat(e.getCause()).isInstanceOf(IllegalStateException.class);
        assertThat(e.getMessage()).contains("'partitionKey' must not be null for sending a Kinesis record");
    }
    message = MessageBuilder.fromMessage(message).setHeader(AwsHeaders.PARTITION_KEY, "fooKey").setHeader(AwsHeaders.SEQUENCE_NUMBER, "10").setHeader("foo", "bar").build();
    this.kinesisSendChannel.send(message);
    ArgumentCaptor<PutRecordRequest> putRecordRequestArgumentCaptor = ArgumentCaptor.forClass(PutRecordRequest.class);
    ArgumentCaptor<AsyncHandler<PutRecordRequest, PutRecordResult>> asyncHandlerArgumentCaptor = ArgumentCaptor.forClass((Class<AsyncHandler<PutRecordRequest, PutRecordResult>>) (Class<?>) AsyncHandler.class);
    verify(this.amazonKinesis).putRecordAsync(putRecordRequestArgumentCaptor.capture(), asyncHandlerArgumentCaptor.capture());
    PutRecordRequest putRecordRequest = putRecordRequestArgumentCaptor.getValue();
    assertThat(putRecordRequest.getStreamName()).isEqualTo("foo");
    assertThat(putRecordRequest.getPartitionKey()).isEqualTo("fooKey");
    assertThat(putRecordRequest.getSequenceNumberForOrdering()).isEqualTo("10");
    assertThat(putRecordRequest.getExplicitHashKey()).isNull();
    Message<?> messageToCheck = new EmbeddedJsonHeadersMessageMapper().toMessage(putRecordRequest.getData().array());
    assertThat(messageToCheck.getHeaders()).contains(entry("foo", "bar"));
    assertThat(messageToCheck.getPayload()).isEqualTo("message".getBytes());
    AsyncHandler<?, ?> asyncHandler = asyncHandlerArgumentCaptor.getValue();
    RuntimeException testingException = new RuntimeException("testingException");
    asyncHandler.onError(testingException);
    verify(this.asyncHandler).onError(eq(testingException));
    message = new GenericMessage<>(new PutRecordsRequest().withStreamName("myStream").withRecords(new PutRecordsRequestEntry().withData(ByteBuffer.wrap("test".getBytes())).withPartitionKey("testKey")));
    this.kinesisSendChannel.send(message);
    ArgumentCaptor<PutRecordsRequest> putRecordsRequestArgumentCaptor = ArgumentCaptor.forClass(PutRecordsRequest.class);
    verify(this.amazonKinesis).putRecordsAsync(putRecordsRequestArgumentCaptor.capture(), any(AsyncHandler.class));
    PutRecordsRequest putRecordsRequest = putRecordsRequestArgumentCaptor.getValue();
    assertThat(putRecordsRequest.getStreamName()).isEqualTo("myStream");
    assertThat(putRecordsRequest.getRecords()).containsExactlyInAnyOrder(new PutRecordsRequestEntry().withData(ByteBuffer.wrap("test".getBytes())).withPartitionKey("testKey"));
}
Also used : AsyncHandler(com.amazonaws.handlers.AsyncHandler) PutRecordsRequestEntry(com.amazonaws.services.kinesis.model.PutRecordsRequestEntry) PutRecordRequest(com.amazonaws.services.kinesis.model.PutRecordRequest) MessageHandlingException(org.springframework.messaging.MessageHandlingException) MessageHandlingException(org.springframework.messaging.MessageHandlingException) EmbeddedJsonHeadersMessageMapper(org.springframework.integration.support.json.EmbeddedJsonHeadersMessageMapper) PutRecordsRequest(com.amazonaws.services.kinesis.model.PutRecordsRequest) Test(org.junit.Test)

Example 7 with PutRecordsRequestEntry

use of com.amazonaws.services.kinesis.model.PutRecordsRequestEntry in project spring-integration-aws by spring-projects.

the class KinesisProducingMessageHandlerTests method testKinesisMessageHandler.

@Test
@SuppressWarnings("unchecked")
public void testKinesisMessageHandler() {
    Message<?> message = MessageBuilder.withPayload("message").build();
    try {
        this.kinesisSendChannel.send(message);
    } catch (Exception e) {
        assertThat(e).isInstanceOf(MessageHandlingException.class);
        assertThat(e.getCause()).isInstanceOf(IllegalStateException.class);
        assertThat(e.getMessage()).contains("'stream' must not be null for sending a Kinesis record");
    }
    this.kinesisMessageHandler.setStream("foo");
    try {
        this.kinesisSendChannel.send(message);
    } catch (Exception e) {
        assertThat(e).isInstanceOf(MessageHandlingException.class);
        assertThat(e.getCause()).isInstanceOf(IllegalStateException.class);
        assertThat(e.getMessage()).contains("'partitionKey' must not be null for sending a Kinesis record");
    }
    message = MessageBuilder.fromMessage(message).setHeader(AwsHeaders.PARTITION_KEY, "fooKey").setHeader(AwsHeaders.SEQUENCE_NUMBER, "10").build();
    this.kinesisSendChannel.send(message);
    Message<?> success = this.successChannel.receive(10000);
    assertThat(success.getHeaders().get(AwsHeaders.PARTITION_KEY)).isEqualTo("fooKey");
    assertThat(success.getHeaders().get(AwsHeaders.SEQUENCE_NUMBER)).isEqualTo("10");
    assertThat(success.getPayload()).isEqualTo("message");
    message = MessageBuilder.fromMessage(message).setHeader(AwsHeaders.PARTITION_KEY, "fooKey").setHeader(AwsHeaders.SEQUENCE_NUMBER, "10").build();
    this.kinesisSendChannel.send(message);
    Message<?> failed = this.errorChannel.receive(10000);
    AwsRequestFailureException putRecordFailure = (AwsRequestFailureException) failed.getPayload();
    assertThat(putRecordFailure.getCause().getMessage()).isEqualTo("putRecordRequestEx");
    assertThat(((PutRecordRequest) putRecordFailure.getRequest()).getStreamName()).isEqualTo("foo");
    assertThat(((PutRecordRequest) putRecordFailure.getRequest()).getPartitionKey()).isEqualTo("fooKey");
    assertThat(((PutRecordRequest) putRecordFailure.getRequest()).getSequenceNumberForOrdering()).isEqualTo("10");
    assertThat(((PutRecordRequest) putRecordFailure.getRequest()).getExplicitHashKey()).isNull();
    assertThat(((PutRecordRequest) putRecordFailure.getRequest()).getData()).isEqualTo(ByteBuffer.wrap("message".getBytes()));
    message = new GenericMessage<>(new PutRecordsRequest().withStreamName("myStream").withRecords(new PutRecordsRequestEntry().withData(ByteBuffer.wrap("test".getBytes())).withPartitionKey("testKey")));
    this.kinesisSendChannel.send(message);
    success = this.successChannel.receive(10000);
    assertThat(((PutRecordsRequest) success.getPayload()).getRecords()).containsExactlyInAnyOrder(new PutRecordsRequestEntry().withData(ByteBuffer.wrap("test".getBytes())).withPartitionKey("testKey"));
    message = new GenericMessage<>(new PutRecordsRequest().withStreamName("myStream").withRecords(new PutRecordsRequestEntry().withData(ByteBuffer.wrap("test".getBytes())).withPartitionKey("testKey")));
    this.kinesisSendChannel.send(message);
    failed = this.errorChannel.receive(10000);
    AwsRequestFailureException putRecordsFailure = (AwsRequestFailureException) failed.getPayload();
    assertThat(putRecordsFailure.getCause().getMessage()).isEqualTo("putRecordsRequestEx");
    assertThat(((PutRecordsRequest) putRecordsFailure.getRequest()).getStreamName()).isEqualTo("myStream");
    assertThat(((PutRecordsRequest) putRecordsFailure.getRequest()).getRecords()).containsExactlyInAnyOrder(new PutRecordsRequestEntry().withData(ByteBuffer.wrap("test".getBytes())).withPartitionKey("testKey"));
}
Also used : AwsRequestFailureException(org.springframework.integration.aws.support.AwsRequestFailureException) PutRecordsRequestEntry(com.amazonaws.services.kinesis.model.PutRecordsRequestEntry) PutRecordRequest(com.amazonaws.services.kinesis.model.PutRecordRequest) MessageHandlingException(org.springframework.messaging.MessageHandlingException) AwsRequestFailureException(org.springframework.integration.aws.support.AwsRequestFailureException) MessageHandlingException(org.springframework.messaging.MessageHandlingException) PutRecordsRequest(com.amazonaws.services.kinesis.model.PutRecordsRequest) Test(org.junit.Test)

Example 8 with PutRecordsRequestEntry

use of com.amazonaws.services.kinesis.model.PutRecordsRequestEntry in project flink by apache.

the class KinesisPubsubClient method sendMessage.

public void sendMessage(String topic, byte[]... messages) {
    for (List<byte[]> partition : Lists.partition(Arrays.asList(messages), 500)) {
        List<PutRecordsRequestEntry> entries = partition.stream().map(msg -> new PutRecordsRequestEntry().withPartitionKey("fakePartitionKey").withData(ByteBuffer.wrap(msg))).collect(Collectors.toList());
        PutRecordsRequest requests = new PutRecordsRequest().withStreamName(topic).withRecords(entries);
        PutRecordsResult putRecordResult = kinesisClient.putRecords(requests);
        for (PutRecordsResultEntry result : putRecordResult.getRecords()) {
            LOG.debug("added record: {}", result.getSequenceNumber());
        }
    }
}
Also used : PutRecordsResultEntry(com.amazonaws.services.kinesis.model.PutRecordsResultEntry) Deadline(org.apache.flink.api.common.time.Deadline) Arrays(java.util.Arrays) Record(com.amazonaws.services.kinesis.model.Record) ConsumerConfigConstants(org.apache.flink.streaming.connectors.kinesis.config.ConsumerConfigConstants) AwsClientBuilder(com.amazonaws.client.builder.AwsClientBuilder) LoggerFactory(org.slf4j.LoggerFactory) PutRecordsRequest(com.amazonaws.services.kinesis.model.PutRecordsRequest) HashMap(java.util.HashMap) Function(java.util.function.Function) GetShardListResult(org.apache.flink.streaming.connectors.kinesis.proxy.GetShardListResult) ByteBuffer(java.nio.ByteBuffer) Lists(org.apache.flink.shaded.guava30.com.google.common.collect.Lists) ArrayList(java.util.ArrayList) PutRecordsResult(com.amazonaws.services.kinesis.model.PutRecordsResult) Duration(java.time.Duration) Map(java.util.Map) AWSCredentialsProvider(com.amazonaws.auth.AWSCredentialsProvider) KinesisProxyInterface(org.apache.flink.streaming.connectors.kinesis.proxy.KinesisProxyInterface) ResourceNotFoundException(com.amazonaws.services.kinesis.model.ResourceNotFoundException) KinesisProxy(org.apache.flink.streaming.connectors.kinesis.proxy.KinesisProxy) GetRecordsResult(com.amazonaws.services.kinesis.model.GetRecordsResult) Logger(org.slf4j.Logger) Properties(java.util.Properties) AmazonKinesis(com.amazonaws.services.kinesis.AmazonKinesis) PutRecordsRequestEntry(com.amazonaws.services.kinesis.model.PutRecordsRequestEntry) StreamShardHandle(org.apache.flink.streaming.connectors.kinesis.model.StreamShardHandle) Collectors(java.util.stream.Collectors) List(java.util.List) AmazonKinesisClientBuilder(com.amazonaws.services.kinesis.AmazonKinesisClientBuilder) AWSUtil(org.apache.flink.streaming.connectors.kinesis.util.AWSUtil) AmazonClientException(com.amazonaws.AmazonClientException) PutRecordsResult(com.amazonaws.services.kinesis.model.PutRecordsResult) PutRecordsRequestEntry(com.amazonaws.services.kinesis.model.PutRecordsRequestEntry) PutRecordsResultEntry(com.amazonaws.services.kinesis.model.PutRecordsResultEntry) PutRecordsRequest(com.amazonaws.services.kinesis.model.PutRecordsRequest)

Example 9 with PutRecordsRequestEntry

use of com.amazonaws.services.kinesis.model.PutRecordsRequestEntry in project flink by apache.

the class ManualExactlyOnceWithStreamReshardingTest method main.

public static void main(String[] args) throws Exception {
    final ParameterTool pt = ParameterTool.fromArgs(args);
    LOG.info("Starting exactly once with stream resharding test");
    final String streamName = "flink-test-" + UUID.randomUUID().toString();
    final String accessKey = pt.getRequired("accessKey");
    final String secretKey = pt.getRequired("secretKey");
    final String region = pt.getRequired("region");
    final Properties configProps = new Properties();
    configProps.setProperty(ConsumerConfigConstants.AWS_ACCESS_KEY_ID, accessKey);
    configProps.setProperty(ConsumerConfigConstants.AWS_SECRET_ACCESS_KEY, secretKey);
    configProps.setProperty(ConsumerConfigConstants.AWS_REGION, region);
    configProps.setProperty(ConsumerConfigConstants.SHARD_DISCOVERY_INTERVAL_MILLIS, "0");
    final AmazonKinesis client = AWSUtil.createKinesisClient(configProps);
    // the stream is first created with 1 shard
    client.createStream(streamName, 1);
    // wait until stream has been created
    DescribeStreamResult status = client.describeStream(streamName);
    LOG.info("status {}", status);
    while (!status.getStreamDescription().getStreamStatus().equals("ACTIVE")) {
        status = client.describeStream(streamName);
        LOG.info("Status of stream {}", status);
        Thread.sleep(1000);
    }
    final Configuration flinkConfig = new Configuration();
    flinkConfig.set(TaskManagerOptions.MANAGED_MEMORY_SIZE, MemorySize.parse("16m"));
    flinkConfig.setString(ConfigConstants.RESTART_STRATEGY_FIXED_DELAY_DELAY, "0 s");
    MiniClusterResource flink = new MiniClusterResource(new MiniClusterResourceConfiguration.Builder().setNumberTaskManagers(1).setNumberSlotsPerTaskManager(8).setConfiguration(flinkConfig).build());
    flink.before();
    final int flinkPort = flink.getRestAddres().getPort();
    try {
        // we have to use a manual generator here instead of the FlinkKinesisProducer
        // because the FlinkKinesisProducer currently has a problem where records will be resent
        // to a shard
        // when resharding happens; this affects the consumer exactly-once validation test and
        // will never pass
        final AtomicReference<Throwable> producerError = new AtomicReference<>();
        Runnable manualGenerate = new Runnable() {

            @Override
            public void run() {
                AmazonKinesis client = AWSUtil.createKinesisClient(configProps);
                int count = 0;
                final int batchSize = 30;
                while (true) {
                    try {
                        Thread.sleep(10);
                        Set<PutRecordsRequestEntry> batch = new HashSet<>();
                        for (int i = count; i < count + batchSize; i++) {
                            if (i >= TOTAL_EVENT_COUNT) {
                                break;
                            }
                            batch.add(new PutRecordsRequestEntry().withData(ByteBuffer.wrap(((i) + "-" + RandomStringUtils.randomAlphabetic(12)).getBytes(ConfigConstants.DEFAULT_CHARSET))).withPartitionKey(UUID.randomUUID().toString()));
                        }
                        count += batchSize;
                        PutRecordsResult result = client.putRecords(new PutRecordsRequest().withStreamName(streamName).withRecords(batch));
                        // and let this test fail
                        if (result.getFailedRecordCount() > 0) {
                            producerError.set(new RuntimeException("The producer has failed records in one of the put batch attempts."));
                            break;
                        }
                        if (count >= TOTAL_EVENT_COUNT) {
                            break;
                        }
                    } catch (Exception e) {
                        producerError.set(e);
                    }
                }
            }
        };
        Thread producerThread = new Thread(manualGenerate);
        producerThread.start();
        final AtomicReference<Throwable> consumerError = new AtomicReference<>();
        Thread consumerThread = ExactlyOnceValidatingConsumerThread.create(TOTAL_EVENT_COUNT, 10000, 2, 500, 500, accessKey, secretKey, region, streamName, consumerError, flinkPort, flinkConfig);
        consumerThread.start();
        // reshard the Kinesis stream while the producer / and consumers are running
        Runnable splitShard = new Runnable() {

            @Override
            public void run() {
                try {
                    // first, split shard in the middle of the hash range
                    Thread.sleep(5000);
                    LOG.info("Splitting shard ...");
                    client.splitShard(streamName, KinesisShardIdGenerator.generateFromShardOrder(0), "170141183460469231731687303715884105727");
                    // wait until the split shard operation finishes updating ...
                    DescribeStreamResult status;
                    Random rand = new Random();
                    do {
                        status = null;
                        while (status == null) {
                            // retry until we get status
                            try {
                                status = client.describeStream(streamName);
                            } catch (LimitExceededException lee) {
                                LOG.warn("LimitExceededException while describing stream ... retrying ...");
                                Thread.sleep(rand.nextInt(1200));
                            }
                        }
                    } while (!status.getStreamDescription().getStreamStatus().equals("ACTIVE"));
                    // then merge again
                    Thread.sleep(7000);
                    LOG.info("Merging shards ...");
                    client.mergeShards(streamName, KinesisShardIdGenerator.generateFromShardOrder(1), KinesisShardIdGenerator.generateFromShardOrder(2));
                } catch (InterruptedException iex) {
                // 
                }
            }
        };
        Thread splitShardThread = new Thread(splitShard);
        splitShardThread.start();
        boolean deadlinePassed = false;
        long deadline = // wait at most for five minutes
        System.currentTimeMillis() + (1000 * 5 * 60);
        // wait until both producer and consumer finishes, or an unexpected error is thrown
        while ((consumerThread.isAlive() || producerThread.isAlive()) && (producerError.get() == null && consumerError.get() == null)) {
            Thread.sleep(1000);
            if (System.currentTimeMillis() >= deadline) {
                LOG.warn("Deadline passed");
                deadlinePassed = true;
                // enough waiting
                break;
            }
        }
        if (producerThread.isAlive()) {
            producerThread.interrupt();
        }
        if (consumerThread.isAlive()) {
            consumerThread.interrupt();
        }
        if (producerError.get() != null) {
            LOG.info("+++ TEST failed! +++");
            throw new RuntimeException("Producer failed", producerError.get());
        }
        if (consumerError.get() != null) {
            LOG.info("+++ TEST failed! +++");
            throw new RuntimeException("Consumer failed", consumerError.get());
        }
        if (!deadlinePassed) {
            LOG.info("+++ TEST passed! +++");
        } else {
            LOG.info("+++ TEST failed! +++");
        }
    } finally {
        client.deleteStream(streamName);
        client.shutdown();
        // stopping flink
        flink.after();
    }
}
Also used : ParameterTool(org.apache.flink.api.java.utils.ParameterTool) PutRecordsRequestEntry(com.amazonaws.services.kinesis.model.PutRecordsRequestEntry) MiniClusterResourceConfiguration(org.apache.flink.runtime.testutils.MiniClusterResourceConfiguration) Configuration(org.apache.flink.configuration.Configuration) Properties(java.util.Properties) PutRecordsResult(com.amazonaws.services.kinesis.model.PutRecordsResult) Random(java.util.Random) MiniClusterResourceConfiguration(org.apache.flink.runtime.testutils.MiniClusterResourceConfiguration) MiniClusterResource(org.apache.flink.runtime.testutils.MiniClusterResource) PutRecordsRequest(com.amazonaws.services.kinesis.model.PutRecordsRequest) HashSet(java.util.HashSet) AtomicReference(java.util.concurrent.atomic.AtomicReference) LimitExceededException(com.amazonaws.services.kinesis.model.LimitExceededException) ExactlyOnceValidatingConsumerThread(org.apache.flink.streaming.connectors.kinesis.testutils.ExactlyOnceValidatingConsumerThread) LimitExceededException(com.amazonaws.services.kinesis.model.LimitExceededException) DescribeStreamResult(com.amazonaws.services.kinesis.model.DescribeStreamResult) AmazonKinesis(com.amazonaws.services.kinesis.AmazonKinesis)

Aggregations

PutRecordsRequestEntry (com.amazonaws.services.kinesis.model.PutRecordsRequestEntry)9 PutRecordsRequest (com.amazonaws.services.kinesis.model.PutRecordsRequest)8 PutRecordsResult (com.amazonaws.services.kinesis.model.PutRecordsResult)4 PutRecordsResultEntry (com.amazonaws.services.kinesis.model.PutRecordsResultEntry)3 List (java.util.List)3 AmazonClientException (com.amazonaws.AmazonClientException)2 AmazonKinesis (com.amazonaws.services.kinesis.AmazonKinesis)2 AmazonKinesisClient (com.amazonaws.services.kinesis.AmazonKinesisClient)2 PutRecordRequest (com.amazonaws.services.kinesis.model.PutRecordRequest)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 Properties (java.util.Properties)2 Test (org.junit.Test)2 MessageHandlingException (org.springframework.messaging.MessageHandlingException)2 AWSCredentialsProvider (com.amazonaws.auth.AWSCredentialsProvider)1 BasicAWSCredentials (com.amazonaws.auth.BasicAWSCredentials)1 AwsClientBuilder (com.amazonaws.client.builder.AwsClientBuilder)1 AsyncHandler (com.amazonaws.handlers.AsyncHandler)1 StaticCredentialsProvider (com.amazonaws.internal.StaticCredentialsProvider)1