-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
76b2340
commit 0f83709
Showing
10 changed files
with
268 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
160 changes: 160 additions & 0 deletions
160
src/it/scala/com/exasol/cloudetl/kinesis/KinesisShardsMetadataReaderIT.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
package com.exasol.cloudetl.kinesis; | ||
|
||
import com.amazonaws.auth.AWSCredentials; | ||
import com.amazonaws.client.builder.AwsClientBuilder; | ||
import com.amazonaws.services.kinesis.AmazonKinesis; | ||
import com.amazonaws.services.kinesis.AmazonKinesisClientBuilder; | ||
import com.exasol.bucketfs.Bucket; | ||
import com.exasol.bucketfs.BucketAccessException; | ||
import com.exasol.containers.ExasolContainer; | ||
import com.exasol.containers.ExasolContainerConstants; | ||
import org.junit.jupiter.api.*; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.testcontainers.containers.localstack.LocalStackContainer; | ||
import org.testcontainers.containers.output.Slf4jLogConsumer; | ||
import org.testcontainers.junit.jupiter.Container; | ||
import org.testcontainers.junit.jupiter.Testcontainers; | ||
|
||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.sql.*; | ||
import java.util.List; | ||
import java.util.concurrent.TimeoutException; | ||
import java.util.stream.Collectors; | ||
|
||
import static com.amazonaws.SDKGlobalConfiguration.AWS_CBOR_DISABLE_SYSTEM_PROPERTY; | ||
import static org.junit.jupiter.api.Assertions.*; | ||
|
||
@Testcontainers | ||
class KinesisShardsMetadataReaderIT { | ||
private static final Logger LOGGER = | ||
LoggerFactory.getLogger(KinesisShardsMetadataReaderIT.class); | ||
private static final String JAR_NAME_PATTERN = "cloud-storage-etl-udfs-"; | ||
public static final String DOCKER_IP_ADDRESS = "172.17.0.1"; | ||
public static final String TEST_STREAM_NAME = "Test_stream"; | ||
@Container | ||
private static final ExasolContainer<? extends ExasolContainer<?>> container = | ||
new ExasolContainer<>( | ||
ExasolContainerConstants.EXASOL_DOCKER_IMAGE_REFERENCE) // | ||
.withLogConsumer(new Slf4jLogConsumer(LOGGER)); | ||
@Container | ||
public static LocalStackContainer kinesisLocalStack = new LocalStackContainer() | ||
.withServices(LocalStackContainer.Service.KINESIS); | ||
private static AmazonKinesis amazonKinesis; | ||
private static String cloudStorageEltUdfsJarName; | ||
private static Statement statement; | ||
private static Connection connection; | ||
|
||
@BeforeAll | ||
static void beforeAll() | ||
throws SQLException, BucketAccessException, InterruptedException, TimeoutException, | ||
IOException { | ||
cloudStorageEltUdfsJarName = findAssembledJarName(); | ||
uploadJarToBucket(); | ||
createStream(); | ||
connection = | ||
container.createConnectionForUser(container.getUsername(), container.getPassword()); | ||
statement = connection.createStatement(); | ||
statement.execute("CREATE SCHEMA kinesis_schema"); | ||
statement.execute("OPEN SCHEMA kinesis_schema"); | ||
statement.execute( | ||
"CREATE OR REPLACE JAVA SET SCRIPT KINESIS_METADATA (...) EMITS (kinesis_shard_id VARCHAR(130), shard_sequence_number VARCHAR(2000)) AS\n" + | ||
" %jvmoption -Dcom.amazonaws.sdk.disableCbor=true;\n" + | ||
" %scriptclass com.exasol.cloudetl.kinesis.KinesisShardsMetadataReader;\n" + | ||
" %jar /buckets/bfsdefault/default/" + cloudStorageEltUdfsJarName + ";\n" + | ||
"/\n"); | ||
// We have to wait until stream is ready to be accessed. | ||
Thread.sleep(40 * 1000); | ||
} | ||
|
||
private static void uploadJarToBucket() | ||
throws InterruptedException, BucketAccessException, TimeoutException { | ||
final Bucket bucket = container.getDefaultBucket(); | ||
final Path pathToRls = Path.of("target", "scala-2.12", cloudStorageEltUdfsJarName); | ||
bucket.uploadFile(pathToRls, cloudStorageEltUdfsJarName); | ||
} | ||
|
||
private static void createStream() { | ||
amazonKinesis = AmazonKinesisClientBuilder.standard() | ||
.withEndpointConfiguration( | ||
kinesisLocalStack.getEndpointConfiguration(LocalStackContainer.Service.KINESIS)) | ||
.withCredentials(kinesisLocalStack.getDefaultCredentialsProvider()).build(); | ||
System.setProperty(AWS_CBOR_DISABLE_SYSTEM_PROPERTY, "true"); | ||
amazonKinesis.createStream(TEST_STREAM_NAME, 3); | ||
} | ||
|
||
@AfterAll | ||
static void releaseResources() throws SQLException { | ||
connection.close(); | ||
statement.close(); | ||
amazonKinesis.shutdown(); | ||
} | ||
|
||
private static String findAssembledJarName() throws IOException { | ||
final List<String> jars = | ||
Files.list(Path.of("target", "scala-2.12")).map(path -> path.getFileName().toString()) | ||
.filter(fileName -> fileName.contains(JAR_NAME_PATTERN)).collect(Collectors.toList()); | ||
if (!jars.isEmpty()) { | ||
return jars.get(0); | ||
} else { | ||
throw new IllegalArgumentException("Cannot find a jar for uploading to the bucket."); | ||
} | ||
} | ||
|
||
@Test | ||
void testMetadataReaderGetsShardsFromStream() throws SQLException { | ||
final ResultSet resultSet = this.executeKinesisMetadataScript("VALUES (('0', '0'))"); | ||
assertAll( | ||
() -> assertTrue(resultSet.next()), | ||
() -> assertEquals("shardId-000000000000", resultSet.getString("KINESIS_SHARD_ID")), | ||
() -> assertNull(resultSet.getString("SHARD_SEQUENCE_NUMBER")), | ||
() -> assertTrue(resultSet.next()), | ||
() -> assertEquals("shardId-000000000001", resultSet.getString("KINESIS_SHARD_ID")), | ||
() -> assertNull(resultSet.getString("SHARD_SEQUENCE_NUMBER")), | ||
() -> assertTrue(resultSet.next()), | ||
() -> assertEquals("shardId-000000000002", resultSet.getString("KINESIS_SHARD_ID")), | ||
() -> assertNull(resultSet.getString("SHARD_SEQUENCE_NUMBER")), | ||
() -> assertFalse(resultSet.next())); | ||
} | ||
|
||
@Test | ||
void testMetadataReaderCombineShardsMetadataWithExistingTable() | ||
throws SQLException { | ||
final ResultSet resultSet = this.executeKinesisMetadataScript( | ||
"VALUES (('shardId-000000000000', '1234'), ('shardId-000000000001', '5678'), ('shardId-000000000004', '9012')) "); | ||
assertAll( | ||
() -> assertTrue(resultSet.next()), | ||
() -> assertEquals("shardId-000000000000", resultSet.getString("KINESIS_SHARD_ID")), | ||
() -> assertEquals("1234", resultSet.getString("SHARD_SEQUENCE_NUMBER")), | ||
() -> assertTrue(resultSet.next()), | ||
() -> assertEquals("shardId-000000000001", resultSet.getString("KINESIS_SHARD_ID")), | ||
() -> assertEquals("5678", resultSet.getString("SHARD_SEQUENCE_NUMBER")), | ||
() -> assertTrue(resultSet.next()), | ||
() -> assertEquals("shardId-000000000002", resultSet.getString("KINESIS_SHARD_ID")), | ||
() -> assertNull(resultSet.getString("SHARD_SEQUENCE_NUMBER")), | ||
() -> assertFalse(resultSet.next())); | ||
} | ||
|
||
private ResultSet executeKinesisMetadataScript(final String tableImitatingValues) | ||
throws SQLException { | ||
final AWSCredentials credentials = | ||
kinesisLocalStack.getDefaultCredentialsProvider().getCredentials(); | ||
final AwsClientBuilder.EndpointConfiguration endpointConfiguration = | ||
kinesisLocalStack.getEndpointConfiguration(LocalStackContainer.Service.KINESIS); | ||
System.out.println(endpointConfiguration.getServiceEndpoint()); | ||
final String endpointInsideDocker = | ||
endpointConfiguration.getServiceEndpoint().replaceAll("127.0.0.1", DOCKER_IP_ADDRESS); | ||
final String sql = | ||
"SELECT KINESIS_METADATA('AWS_ACCESS_KEY -> " + credentials.getAWSAccessKeyId() + | ||
";AWS_SECRET_KEY -> " + credentials.getAWSSecretKey() + | ||
";REGION -> " + endpointConfiguration.getSigningRegion() + | ||
";STREAM_NAME -> " + TEST_STREAM_NAME + | ||
";AWS_SERVICE_ENDPOINT -> " + endpointInsideDocker + | ||
"', KINESIS_SHARD_ID, SHARD_SEQUENCE_NUMBER) \n" + | ||
"FROM (" + tableImitatingValues + | ||
" AS t(KINESIS_SHARD_ID, SHARD_SEQUENCE_NUMBER)) ORDER BY KINESIS_SHARD_ID"; | ||
return statement.executeQuery(sql); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.