amazon-kinesis-client/amazon-kinesis-client-multilang/src/main/java/software/amazon/kinesis/multilang/LineReaderTask.java

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

183 lines
6.5 KiB
Java
Raw Normal View History

/*
* Copyright 2019 Amazon.com, Inc. or its affiliates.
* 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 software.amazon.kinesis.multilang;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.concurrent.Callable;
Release 2.0.0 of the Amazon Kinesis Client for Java * Added support for Enhanced Fan Out. Enhanced Fan Out provides for lower end to end latency, and increased number of consumers per stream. * Records are now delivered via streaming, reducing end-to-end latency. * The Amazon Kinesis Client will automatically register a new consumer if required. When registering a new consumer, the Kinesis Client will default to the application name unless configured otherwise. * New configuration options are available to configure Enhanced Fan Out. * `SubscribeToShard` maintains long lived connections with Kinesis, which in the AWS Java SDK 2.0 is limited by default. The `KinesisClientUtil` has been added to assist configuring the `maxConcurrency` of the `KinesisAsyncClient`. __WARNING: The Amazon Kinesis Client may see significantly increased latency, unless the `KinesisAsyncClient` is configured to have a `maxConcurrency` high enough to allow all leases plus additional usages of the `KinesisAsyncClient`.__ | Name | Default | Description | |-----------------|---------|---------------------------------------------------------------------------------------------------------------------| | consumerArn | Unset | The ARN for an already created consumer. If this is set, the Kinesis Client will not attempt to create a consumer. | | streamName | Unset | The name of the stream that a consumer should be create for if necessary | | consumerName | Unset | The name of the consumer to create. If this is not set the applicationName will be used instead. | | applicationName | Unset | The name of the application. This is used as the name of the consumer unless consumerName is set. | * Modular Configuration of the Kinesis Client The Kinesis Client has migrated to a modular configuration system, and the `KinesisClientLibConfiguration` class has been removed. Configuration has been split into 7 classes. Default versions of the configuration can be created from the `ConfigsBuilder`. Please see the migration guide for more information * `CheckpointConfig` * `CoordinatorConfig` * `LeaseManagementConfig` * `LifecycleConfig` * `MetricsConfig` * `ProcessorConfig` * `RetrievalConfig` * Upgraded to AWS Java SDK 2.0 The Kinesis Client now uses the AWS Java SDK 2.0. The dependency on AWS Java SDK 1.11 has been removed. All configurations will only accept 2.0 clients. * When configuring the `KinesisAsyncClient` the `KinesisClientUtil#createKinesisAsyncClient` can be used to configure the Kinesis Client * __If you need support for AWS Java SDK 1.11 you will need to add a direct dependency.__ __When adding a dependency you must ensure that the 1.11 versions of Jackson dependencies are excluded__ Please see the migration guide for more information * MultiLangDaemon is now a separate module The MultiLangDaemon has been separated to its own Maven module and is no longer available in `amazon-kinesis-client`. To include the MultiLangDaemon, add a dependency on `amazon-kinesis-client-multilang`.
2018-08-02 17:57:11 +00:00
import lombok.extern.slf4j.Slf4j;
/**
* This abstract class captures the process of reading from an input stream. Three methods must be provided for
* implementations to work.
* <ol>
* <li> {@link #handleLine(String)}</li>
* <li> {@link #returnAfterEndOfInput()}</li>
* <li> {@link #returnAfterException(Exception)}</li>
* </ol>
2024-05-20 18:26:15 +00:00
*
* @param <T>
*/
Release 2.0.0 of the Amazon Kinesis Client for Java * Added support for Enhanced Fan Out. Enhanced Fan Out provides for lower end to end latency, and increased number of consumers per stream. * Records are now delivered via streaming, reducing end-to-end latency. * The Amazon Kinesis Client will automatically register a new consumer if required. When registering a new consumer, the Kinesis Client will default to the application name unless configured otherwise. * New configuration options are available to configure Enhanced Fan Out. * `SubscribeToShard` maintains long lived connections with Kinesis, which in the AWS Java SDK 2.0 is limited by default. The `KinesisClientUtil` has been added to assist configuring the `maxConcurrency` of the `KinesisAsyncClient`. __WARNING: The Amazon Kinesis Client may see significantly increased latency, unless the `KinesisAsyncClient` is configured to have a `maxConcurrency` high enough to allow all leases plus additional usages of the `KinesisAsyncClient`.__ | Name | Default | Description | |-----------------|---------|---------------------------------------------------------------------------------------------------------------------| | consumerArn | Unset | The ARN for an already created consumer. If this is set, the Kinesis Client will not attempt to create a consumer. | | streamName | Unset | The name of the stream that a consumer should be create for if necessary | | consumerName | Unset | The name of the consumer to create. If this is not set the applicationName will be used instead. | | applicationName | Unset | The name of the application. This is used as the name of the consumer unless consumerName is set. | * Modular Configuration of the Kinesis Client The Kinesis Client has migrated to a modular configuration system, and the `KinesisClientLibConfiguration` class has been removed. Configuration has been split into 7 classes. Default versions of the configuration can be created from the `ConfigsBuilder`. Please see the migration guide for more information * `CheckpointConfig` * `CoordinatorConfig` * `LeaseManagementConfig` * `LifecycleConfig` * `MetricsConfig` * `ProcessorConfig` * `RetrievalConfig` * Upgraded to AWS Java SDK 2.0 The Kinesis Client now uses the AWS Java SDK 2.0. The dependency on AWS Java SDK 1.11 has been removed. All configurations will only accept 2.0 clients. * When configuring the `KinesisAsyncClient` the `KinesisClientUtil#createKinesisAsyncClient` can be used to configure the Kinesis Client * __If you need support for AWS Java SDK 1.11 you will need to add a direct dependency.__ __When adding a dependency you must ensure that the 1.11 versions of Jackson dependencies are excluded__ Please see the migration guide for more information * MultiLangDaemon is now a separate module The MultiLangDaemon has been separated to its own Maven module and is no longer available in `amazon-kinesis-client`. To include the MultiLangDaemon, add a dependency on `amazon-kinesis-client-multilang`.
2018-08-02 17:57:11 +00:00
@Slf4j
abstract class LineReaderTask<T> implements Callable<T> {
private BufferedReader reader;
private String description;
private String shardId;
2024-05-20 18:26:15 +00:00
LineReaderTask() {}
/**
* Reads lines off the input stream until a return value is set, or an exception is encountered, or the end of the
* input stream is reached. Will call the appropriate methods in each case. This is the shared piece of logic
* between any tasks that need to read from a child process's STDOUT or STDERR.
*/
@Override
public T call() throws Exception {
String nextLine = null;
try {
Release 2.0.0 of the Amazon Kinesis Client for Java * Added support for Enhanced Fan Out. Enhanced Fan Out provides for lower end to end latency, and increased number of consumers per stream. * Records are now delivered via streaming, reducing end-to-end latency. * The Amazon Kinesis Client will automatically register a new consumer if required. When registering a new consumer, the Kinesis Client will default to the application name unless configured otherwise. * New configuration options are available to configure Enhanced Fan Out. * `SubscribeToShard` maintains long lived connections with Kinesis, which in the AWS Java SDK 2.0 is limited by default. The `KinesisClientUtil` has been added to assist configuring the `maxConcurrency` of the `KinesisAsyncClient`. __WARNING: The Amazon Kinesis Client may see significantly increased latency, unless the `KinesisAsyncClient` is configured to have a `maxConcurrency` high enough to allow all leases plus additional usages of the `KinesisAsyncClient`.__ | Name | Default | Description | |-----------------|---------|---------------------------------------------------------------------------------------------------------------------| | consumerArn | Unset | The ARN for an already created consumer. If this is set, the Kinesis Client will not attempt to create a consumer. | | streamName | Unset | The name of the stream that a consumer should be create for if necessary | | consumerName | Unset | The name of the consumer to create. If this is not set the applicationName will be used instead. | | applicationName | Unset | The name of the application. This is used as the name of the consumer unless consumerName is set. | * Modular Configuration of the Kinesis Client The Kinesis Client has migrated to a modular configuration system, and the `KinesisClientLibConfiguration` class has been removed. Configuration has been split into 7 classes. Default versions of the configuration can be created from the `ConfigsBuilder`. Please see the migration guide for more information * `CheckpointConfig` * `CoordinatorConfig` * `LeaseManagementConfig` * `LifecycleConfig` * `MetricsConfig` * `ProcessorConfig` * `RetrievalConfig` * Upgraded to AWS Java SDK 2.0 The Kinesis Client now uses the AWS Java SDK 2.0. The dependency on AWS Java SDK 1.11 has been removed. All configurations will only accept 2.0 clients. * When configuring the `KinesisAsyncClient` the `KinesisClientUtil#createKinesisAsyncClient` can be used to configure the Kinesis Client * __If you need support for AWS Java SDK 1.11 you will need to add a direct dependency.__ __When adding a dependency you must ensure that the 1.11 versions of Jackson dependencies are excluded__ Please see the migration guide for more information * MultiLangDaemon is now a separate module The MultiLangDaemon has been separated to its own Maven module and is no longer available in `amazon-kinesis-client`. To include the MultiLangDaemon, add a dependency on `amazon-kinesis-client-multilang`.
2018-08-02 17:57:11 +00:00
log.info("Starting: {}", description);
while ((nextLine = reader.readLine()) != null) {
HandleLineResult<T> result = handleLine(nextLine);
if (result.hasReturnValue()) {
return result.returnValue();
}
}
} catch (IOException e) {
return returnAfterException(e);
}
Release 2.0.0 of the Amazon Kinesis Client for Java * Added support for Enhanced Fan Out. Enhanced Fan Out provides for lower end to end latency, and increased number of consumers per stream. * Records are now delivered via streaming, reducing end-to-end latency. * The Amazon Kinesis Client will automatically register a new consumer if required. When registering a new consumer, the Kinesis Client will default to the application name unless configured otherwise. * New configuration options are available to configure Enhanced Fan Out. * `SubscribeToShard` maintains long lived connections with Kinesis, which in the AWS Java SDK 2.0 is limited by default. The `KinesisClientUtil` has been added to assist configuring the `maxConcurrency` of the `KinesisAsyncClient`. __WARNING: The Amazon Kinesis Client may see significantly increased latency, unless the `KinesisAsyncClient` is configured to have a `maxConcurrency` high enough to allow all leases plus additional usages of the `KinesisAsyncClient`.__ | Name | Default | Description | |-----------------|---------|---------------------------------------------------------------------------------------------------------------------| | consumerArn | Unset | The ARN for an already created consumer. If this is set, the Kinesis Client will not attempt to create a consumer. | | streamName | Unset | The name of the stream that a consumer should be create for if necessary | | consumerName | Unset | The name of the consumer to create. If this is not set the applicationName will be used instead. | | applicationName | Unset | The name of the application. This is used as the name of the consumer unless consumerName is set. | * Modular Configuration of the Kinesis Client The Kinesis Client has migrated to a modular configuration system, and the `KinesisClientLibConfiguration` class has been removed. Configuration has been split into 7 classes. Default versions of the configuration can be created from the `ConfigsBuilder`. Please see the migration guide for more information * `CheckpointConfig` * `CoordinatorConfig` * `LeaseManagementConfig` * `LifecycleConfig` * `MetricsConfig` * `ProcessorConfig` * `RetrievalConfig` * Upgraded to AWS Java SDK 2.0 The Kinesis Client now uses the AWS Java SDK 2.0. The dependency on AWS Java SDK 1.11 has been removed. All configurations will only accept 2.0 clients. * When configuring the `KinesisAsyncClient` the `KinesisClientUtil#createKinesisAsyncClient` can be used to configure the Kinesis Client * __If you need support for AWS Java SDK 1.11 you will need to add a direct dependency.__ __When adding a dependency you must ensure that the 1.11 versions of Jackson dependencies are excluded__ Please see the migration guide for more information * MultiLangDaemon is now a separate module The MultiLangDaemon has been separated to its own Maven module and is no longer available in `amazon-kinesis-client`. To include the MultiLangDaemon, add a dependency on `amazon-kinesis-client-multilang`.
2018-08-02 17:57:11 +00:00
log.info("Stopping: {}", description);
return returnAfterEndOfInput();
}
/**
* Handle a line read from the input stream. The return value indicates whether the enclosing read-loop should
* return from the {@link #call()} function by having a value, indicating that value should be returned immediately
* without reading further, or not having a value, indicating that more lines of input need to be read before
* returning.
2024-05-20 18:26:15 +00:00
*
* @param line A line read from the input stream.
* @return HandleLineResult<T> which may or may not have a has return value, indicating to return or not return yet
* respectively.
*/
protected abstract HandleLineResult<T> handleLine(String line);
/**
* This method will be called if there is an error while reading from the input stream. The return value of this
* method will be returned as the result of this Callable unless an Exception is thrown. If an Exception is thrown
* then that exception will be thrown by the Callable.
2024-05-20 18:26:15 +00:00
*
* @param e An exception that occurred while reading from the input stream.
* @return What to return.
*/
protected abstract T returnAfterException(Exception e) throws Exception;
/**
* This method will be called once the end of the input stream is reached. The return value of this method will be
* returned as the result of this Callable. Implementations of this method are welcome to throw a runtime exception
* to indicate that the task was unsuccessful.
2024-05-20 18:26:15 +00:00
*
* @return What to return.
*/
protected abstract T returnAfterEndOfInput();
/**
* Allows subclasses to provide more detailed logs. Specifically, this allows the drain tasks and GetNextMessageTask
* to log which shard they're working on.
2024-05-20 18:26:15 +00:00
*
* @return The shard id
*/
public String getShardId() {
return this.shardId;
}
/**
* The description should be a string explaining what this particular LineReader class does.
2024-05-20 18:26:15 +00:00
*
* @return The description.
*/
public String getDescription() {
return this.description;
}
/**
* The result of a call to {@link LineReaderTask#handleLine(String)}. Allows implementations of that method to
* indicate whether a particular invocation of that method produced a return for this task or not. If a return value
* doesn't exist the {@link #call()} method will continue to the next line.
2024-05-20 18:26:15 +00:00
*
* @param <V>
*/
protected class HandleLineResult<V> {
private boolean hasReturnValue;
private V returnValue;
HandleLineResult() {
this.hasReturnValue = false;
}
HandleLineResult(V returnValue) {
this.hasReturnValue = true;
this.returnValue = returnValue;
}
boolean hasReturnValue() {
return this.hasReturnValue;
}
V returnValue() {
if (hasReturnValue()) {
return this.returnValue;
} else {
throw new RuntimeException("There was no value to return.");
}
}
}
/**
* An initialization method allows us to delay setting the attributes of this class. Some of the attributes, stream
* and shardId, are not known to the {@link MultiLangRecordProcessorFactory} when it constructs a
Release 2.0.0 of the Amazon Kinesis Client for Java * Added support for Enhanced Fan Out. Enhanced Fan Out provides for lower end to end latency, and increased number of consumers per stream. * Records are now delivered via streaming, reducing end-to-end latency. * The Amazon Kinesis Client will automatically register a new consumer if required. When registering a new consumer, the Kinesis Client will default to the application name unless configured otherwise. * New configuration options are available to configure Enhanced Fan Out. * `SubscribeToShard` maintains long lived connections with Kinesis, which in the AWS Java SDK 2.0 is limited by default. The `KinesisClientUtil` has been added to assist configuring the `maxConcurrency` of the `KinesisAsyncClient`. __WARNING: The Amazon Kinesis Client may see significantly increased latency, unless the `KinesisAsyncClient` is configured to have a `maxConcurrency` high enough to allow all leases plus additional usages of the `KinesisAsyncClient`.__ | Name | Default | Description | |-----------------|---------|---------------------------------------------------------------------------------------------------------------------| | consumerArn | Unset | The ARN for an already created consumer. If this is set, the Kinesis Client will not attempt to create a consumer. | | streamName | Unset | The name of the stream that a consumer should be create for if necessary | | consumerName | Unset | The name of the consumer to create. If this is not set the applicationName will be used instead. | | applicationName | Unset | The name of the application. This is used as the name of the consumer unless consumerName is set. | * Modular Configuration of the Kinesis Client The Kinesis Client has migrated to a modular configuration system, and the `KinesisClientLibConfiguration` class has been removed. Configuration has been split into 7 classes. Default versions of the configuration can be created from the `ConfigsBuilder`. Please see the migration guide for more information * `CheckpointConfig` * `CoordinatorConfig` * `LeaseManagementConfig` * `LifecycleConfig` * `MetricsConfig` * `ProcessorConfig` * `RetrievalConfig` * Upgraded to AWS Java SDK 2.0 The Kinesis Client now uses the AWS Java SDK 2.0. The dependency on AWS Java SDK 1.11 has been removed. All configurations will only accept 2.0 clients. * When configuring the `KinesisAsyncClient` the `KinesisClientUtil#createKinesisAsyncClient` can be used to configure the Kinesis Client * __If you need support for AWS Java SDK 1.11 you will need to add a direct dependency.__ __When adding a dependency you must ensure that the 1.11 versions of Jackson dependencies are excluded__ Please see the migration guide for more information * MultiLangDaemon is now a separate module The MultiLangDaemon has been separated to its own Maven module and is no longer available in `amazon-kinesis-client`. To include the MultiLangDaemon, add a dependency on `amazon-kinesis-client-multilang`.
2018-08-02 17:57:11 +00:00
* {@link MultiLangShardRecordProcessor} but are later determined when
* {@link MultiLangShardRecordProcessor#initialize(String)} is called. So we follow a pattern where the attributes are
* set inside this method instead of the constructor so that this object will be initialized when all its attributes
* are known to the record processor.
2024-05-20 18:26:15 +00:00
*
* @param stream
* @param shardId
* @param description
* @return
*/
protected LineReaderTask<T> initialize(InputStream stream, String shardId, String description) {
return this.initialize(new BufferedReader(new InputStreamReader(stream)), shardId, description);
}
/**
* @param reader
* @param shardId
* @param description
* @return
*/
protected LineReaderTask<T> initialize(BufferedReader reader, String shardId, String description) {
this.reader = reader;
this.shardId = shardId;
this.description = description;
return this;
}
}