From f9042d777b66e5d99ffa7611438503f2f03b2497 Mon Sep 17 00:00:00 2001 From: scmacdon Date: Mon, 10 Jun 2024 08:33:41 -0400 Subject: [PATCH] added more lintered files --- .../kotlin/com/example/iot/IotScenario.kt | 1 - .../kendra/CreateIndexAndDataSourceExample.kt | 3 +- kotlin/services/keyspaces/build.gradle.kts | 2 +- .../com/example/keyspace/HelloKeyspaces.kt | 70 +- .../com/example/keyspace/ScenarioKeyspaces.kt | 1195 +++++++++-------- .../keyspaces/src/test/kotlin/KeyspaceTest.kt | 8 +- 6 files changed, 674 insertions(+), 605 deletions(-) diff --git a/kotlin/services/iot/src/main/kotlin/com/example/iot/IotScenario.kt b/kotlin/services/iot/src/main/kotlin/com/example/iot/IotScenario.kt index 6b48c0ef3d8..3fca83df9ca 100644 --- a/kotlin/services/iot/src/main/kotlin/com/example/iot/IotScenario.kt +++ b/kotlin/services/iot/src/main/kotlin/com/example/iot/IotScenario.kt @@ -397,7 +397,6 @@ suspend fun listCertificates() { // snippet-start:[iot.kotlin.describe.endpoint.main] suspend fun describeEndpoint(): String? { val request = DescribeEndpointRequest {} - IotClient { region = "us-east-1" }.use { iotClient -> val endpointResponse = iotClient.describeEndpoint(request) val endpointUrl: String? = endpointResponse.endpointAddress diff --git a/kotlin/services/kendra/src/main/kotlin/com/example/kendra/CreateIndexAndDataSourceExample.kt b/kotlin/services/kendra/src/main/kotlin/com/example/kendra/CreateIndexAndDataSourceExample.kt index e3848c42408..392119b2859 100644 --- a/kotlin/services/kendra/src/main/kotlin/com/example/kendra/CreateIndexAndDataSourceExample.kt +++ b/kotlin/services/kendra/src/main/kotlin/com/example/kendra/CreateIndexAndDataSourceExample.kt @@ -126,7 +126,6 @@ suspend fun createDataSource( } KendraClient { region = "us-east-1" }.use { kendra -> - val createDataSourceResponse = kendra.createDataSource(createDataSourceRequest) println("Response of creating data source $createDataSourceResponse") val dataSourceId = createDataSourceResponse.id @@ -156,7 +155,7 @@ suspend fun createDataSource( // snippet-start:[kendra.kotlin.start.datasource.main] suspend fun startDataSource( indexIdVal: String?, - dataSourceId: String?, + dataSourceId: String? ) { println("Synchronize the data source $dataSourceId") val startDataSourceSyncJobRequest = diff --git a/kotlin/services/keyspaces/build.gradle.kts b/kotlin/services/keyspaces/build.gradle.kts index fc215686662..586e29faa64 100644 --- a/kotlin/services/keyspaces/build.gradle.kts +++ b/kotlin/services/keyspaces/build.gradle.kts @@ -27,7 +27,7 @@ repositories { } apply(plugin = "org.jlleitschuh.gradle.ktlint") dependencies { - implementation("aws.sdk.kotlin:keyspaces:1.0.30") + implementation("aws.sdk.kotlin:keyspaces:1.2.28") implementation("com.datastax.oss:java-driver-core:4.15.0") implementation("aws.smithy.kotlin:http-client-engine-okhttp:0.30.0") implementation("aws.smithy.kotlin:http-client-engine-crt:0.30.0") diff --git a/kotlin/services/keyspaces/src/main/kotlin/com/example/keyspace/HelloKeyspaces.kt b/kotlin/services/keyspaces/src/main/kotlin/com/example/keyspace/HelloKeyspaces.kt index 1e80fd86075..3e53a787273 100644 --- a/kotlin/services/keyspaces/src/main/kotlin/com/example/keyspace/HelloKeyspaces.kt +++ b/kotlin/services/keyspaces/src/main/kotlin/com/example/keyspace/HelloKeyspaces.kt @@ -1,34 +1,36 @@ -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 - -package com.example.keyspace - -import aws.sdk.kotlin.services.keyspaces.KeyspacesClient -import aws.sdk.kotlin.services.keyspaces.model.ListKeyspacesRequest - -// snippet-start:[keyspace.kotlin.hello.main] -/** -Before running this Kotlin code example, set up your development environment, including your credentials. - -For more information, see the following documentation topic: - -https://docs.aws.amazon.com/sdk-for-kotlin/latest/developer-guide/setup.html -*/ - -suspend fun main() { - listKeyspaces() -} - -suspend fun listKeyspaces() { - val keyspacesRequest = ListKeyspacesRequest { - maxResults = 10 - } - - KeyspacesClient { region = "us-east-1" }.use { keyClient -> - val response = keyClient.listKeyspaces(keyspacesRequest) - response.keyspaces?.forEach { keyspace -> - println("The name of the keyspace is ${keyspace.keyspaceName}") - } - } -} -// snippet-end:[keyspace.kotlin.hello.main] +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package com.example.keyspace + +import aws.sdk.kotlin.services.keyspaces.KeyspacesClient +import aws.sdk.kotlin.services.keyspaces.model.ListKeyspacesRequest + +// snippet-start:[keyspace.kotlin.hello.main] + +/** +Before running this Kotlin code example, set up your development environment, including your credentials. + +For more information, see the following documentation topic: + +https://docs.aws.amazon.com/sdk-for-kotlin/latest/developer-guide/setup.html +*/ + +suspend fun main() { + listKeyspaces() +} + +suspend fun listKeyspaces() { + val keyspacesRequest = + ListKeyspacesRequest { + maxResults = 10 + } + + KeyspacesClient { region = "us-east-1" }.use { keyClient -> + val response = keyClient.listKeyspaces(keyspacesRequest) + response.keyspaces?.forEach { keyspace -> + println("The name of the keyspace is ${keyspace.keyspaceName}") + } + } +} +// snippet-end:[keyspace.kotlin.hello.main] diff --git a/kotlin/services/keyspaces/src/main/kotlin/com/example/keyspace/ScenarioKeyspaces.kt b/kotlin/services/keyspaces/src/main/kotlin/com/example/keyspace/ScenarioKeyspaces.kt index 5587407934b..f69d373a31a 100644 --- a/kotlin/services/keyspaces/src/main/kotlin/com/example/keyspace/ScenarioKeyspaces.kt +++ b/kotlin/services/keyspaces/src/main/kotlin/com/example/keyspace/ScenarioKeyspaces.kt @@ -1,563 +1,632 @@ -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 - -package com.example.keyspace - -import aws.sdk.kotlin.services.keyspaces.KeyspacesClient -import aws.sdk.kotlin.services.keyspaces.model.ColumnDefinition -import aws.sdk.kotlin.services.keyspaces.model.CreateKeyspaceRequest -import aws.sdk.kotlin.services.keyspaces.model.CreateTableRequest -import aws.sdk.kotlin.services.keyspaces.model.DeleteKeyspaceRequest -import aws.sdk.kotlin.services.keyspaces.model.DeleteTableRequest -import aws.sdk.kotlin.services.keyspaces.model.GetKeyspaceRequest -import aws.sdk.kotlin.services.keyspaces.model.GetKeyspaceResponse -import aws.sdk.kotlin.services.keyspaces.model.GetTableRequest -import aws.sdk.kotlin.services.keyspaces.model.GetTableResponse -import aws.sdk.kotlin.services.keyspaces.model.ListKeyspacesRequest -import aws.sdk.kotlin.services.keyspaces.model.ListTablesRequest -import aws.sdk.kotlin.services.keyspaces.model.PartitionKey -import aws.sdk.kotlin.services.keyspaces.model.PointInTimeRecovery -import aws.sdk.kotlin.services.keyspaces.model.PointInTimeRecoveryStatus -import aws.sdk.kotlin.services.keyspaces.model.ResourceNotFoundException -import aws.sdk.kotlin.services.keyspaces.model.RestoreTableRequest -import aws.sdk.kotlin.services.keyspaces.model.SchemaDefinition -import aws.sdk.kotlin.services.keyspaces.model.UpdateTableRequest -import aws.sdk.kotlin.services.keyspaces.paginators.listKeyspacesPaginated -import aws.sdk.kotlin.services.keyspaces.paginators.listTablesPaginated -import com.datastax.oss.driver.api.core.ConsistencyLevel -import com.datastax.oss.driver.api.core.CqlSession -import com.datastax.oss.driver.api.core.config.DriverConfigLoader -import com.datastax.oss.driver.api.core.cql.BatchStatement -import com.datastax.oss.driver.api.core.cql.DefaultBatchType -import com.datastax.oss.driver.api.core.cql.PreparedStatement -import com.datastax.oss.driver.api.core.cql.Row -import com.fasterxml.jackson.core.JsonFactory -import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.databind.node.ObjectNode -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.transform -import java.io.File -import java.time.ZoneOffset -import java.time.ZonedDateTime -import java.util.Date - -// snippet-start:[keyspace.kotlin.scenario.main] -/** - Before running this Kotlin code example, set up your development environment, including your credentials. - - For more information, see the following documentation topic: - - https://docs.aws.amazon.com/sdk-for-kotlin/latest/developer-guide/setup.html - - This example uses a secure file format to hold certificate information for - Kotlin applications. This is required to make a connection to Amazon Keyspaces. - For more information, see the following documentation topic: - - https://docs.aws.amazon.com/keyspaces/latest/devguide/using_java_driver.html - - This Kotlin example performs the following tasks: - - 1. Create a keyspace. - 2. Check for keyspace existence. - 3. List keyspaces using a paginator. - 4. Create a table with a simple movie data schema and enable point-in-time recovery. - 5. Check for the table to be in an Active state. - 6. List all tables in the keyspace. - 7. Use a Cassandra driver to insert some records into the Movie table. - 8. Get all records from the Movie table. - 9. Get a specific Movie. - 10. Get a UTC timestamp for the current time. - 11. Update the table schema to add a ‘watched’ Boolean column. - 12. Update an item as watched. - 13. Query for items with watched = True. - 14. Restore the table back to the previous state using the timestamp. - 15. Check for completion of the restore action. - 16. Delete the table. - 17. Confirm that both tables are deleted. - 18. Delete the keyspace. - */ - -/* - Usage: - fileName - The name of the JSON file that contains movie data. (Get this file from the GitHub repo at resources/sample_file.) - keyspaceName - The name of the keyspace to create. - */ -val DASHES: String = String(CharArray(80)).replace("\u0000", "-") -suspend fun main() { - val fileName = "" - val keyspaceName = "" - val titleUpdate = "The Family" - val yearUpdate = 2013 - val tableName = "MovieKotlin" - val tableNameRestore = "MovieRestore" - - val loader = DriverConfigLoader.fromClasspath("application.conf") - val session = CqlSession.builder() - .withConfigLoader(loader) - .build() - - println(DASHES) - println("Welcome to the Amazon Keyspaces example scenario.") - println(DASHES) - - println(DASHES) - println("1. Create a keyspace.") - createKeySpace(keyspaceName) - println(DASHES) - - println(DASHES) - delay(5000) - println("2. Check for keyspace existence.") - checkKeyspaceExistence(keyspaceName) - println(DASHES) - - println(DASHES) - println("3. List keyspaces using a paginator.") - listKeyspacesPaginator() - println(DASHES) - - println(DASHES) - println("4. Create a table with a simple movie data schema and enable point-in-time recovery.") - createTable(keyspaceName, tableName) - println(DASHES) - - println(DASHES) - println("5. Check for the table to be in an Active state.") - delay(6000) - checkTable(keyspaceName, tableName) - println(DASHES) - - println(DASHES) - println("6. List all tables in the keyspace.") - listTables(keyspaceName) - println(DASHES) - - println(DASHES) - println("7. Use a Cassandra driver to insert some records into the Movie table.") - delay(6000) - loadData(session, fileName, keyspaceName) - println(DASHES) - - println(DASHES) - println("8. Get all records from the Movie table.") - getMovieData(session, keyspaceName) - println(DASHES) - - println(DASHES) - println("9. Get a specific Movie.") - getSpecificMovie(session, keyspaceName) - println(DASHES) - - println(DASHES) - println("10. Get a UTC timestamp for the current time.") - val utc = ZonedDateTime.now(ZoneOffset.UTC) - println("DATETIME = ${Date.from(utc.toInstant())}") - println(DASHES) - - println(DASHES) - println("11. Update the table schema to add a watched Boolean column.") - updateTable(keyspaceName, tableName) - println(DASHES) - - println(DASHES) - println("12. Update an item as watched.") - delay(10000) // Wait 10 seconds for the update. - updateRecord(session, keyspaceName, titleUpdate, yearUpdate) - println(DASHES) - - println(DASHES) - println("13. Query for items with watched = True.") - getWatchedData(session, keyspaceName) - println(DASHES) - - println(DASHES) - println("14. Restore the table back to the previous state using the timestamp.") - println("Note that the restore operation can take up to 20 minutes.") - restoreTable(keyspaceName, utc) - println(DASHES) - - println(DASHES) - println("15. Check for completion of the restore action.") - delay(5000) - checkRestoredTable(keyspaceName, "MovieRestore") - println(DASHES) - - println(DASHES) - println("16. Delete both tables.") - deleteTable(keyspaceName, tableName) - deleteTable(keyspaceName, tableNameRestore) - println(DASHES) - - println(DASHES) - println("17. Confirm that both tables are deleted.") - checkTableDelete(keyspaceName, tableName) - checkTableDelete(keyspaceName, tableNameRestore) - println(DASHES) - - println(DASHES) - println("18. Delete the keyspace.") - deleteKeyspace(keyspaceName) - println(DASHES) - - println(DASHES) - println("The scenario has completed successfully.") - println(DASHES) -} - -// snippet-start:[keyspace.kotlin.scenario.delete.keyspace.main] -suspend fun deleteKeyspace(keyspaceNameVal: String?) { - val deleteKeyspaceRequest = DeleteKeyspaceRequest { - keyspaceName = keyspaceNameVal - } - - KeyspacesClient { region = "us-east-1" }.use { keyClient -> - keyClient.deleteKeyspace(deleteKeyspaceRequest) - } -} -// snippet-end:[keyspace.kotlin.scenario.delete.keyspace.main] - -suspend fun checkTableDelete(keyspaceNameVal: String?, tableNameVal: String?) { - var status: String - var response: GetTableResponse - val tableRequest = GetTableRequest { - keyspaceName = keyspaceNameVal - tableName = tableNameVal - } - - try { - KeyspacesClient { region = "us-east-1" }.use { keyClient -> - // Keep looping until the table cannot be found and a ResourceNotFoundException is thrown. - while (true) { - response = keyClient.getTable(tableRequest) - status = response.status.toString() - println(". The table status is $status") - delay(500) - } - } - } catch (e: ResourceNotFoundException) { - println(e.message) - } - println("The table is deleted") -} - -// snippet-start:[keyspace.kotlin.scenario.delete.table.main] -suspend fun deleteTable(keyspaceNameVal: String?, tableNameVal: String?) { - val tableRequest = DeleteTableRequest { - keyspaceName = keyspaceNameVal - tableName = tableNameVal - } - - KeyspacesClient { region = "us-east-1" }.use { keyClient -> - keyClient.deleteTable(tableRequest) - } -} -// snippet-end:[keyspace.kotlin.scenario.delete.table.main] - -suspend fun checkRestoredTable(keyspaceNameVal: String?, tableNameVal: String?) { - var tableStatus = false - var status: String - var response: GetTableResponse? = null - - val tableRequest = GetTableRequest { - keyspaceName = keyspaceNameVal - tableName = tableNameVal - } - - KeyspacesClient { region = "us-east-1" }.use { keyClient -> - while (!tableStatus) { - response = keyClient.getTable(tableRequest) - status = response!!.status.toString() - println("The table status is $status") - - if (status.compareTo("ACTIVE") == 0) { - tableStatus = true - } - delay(500) - } - - val cols = response!!.schemaDefinition?.allColumns - if (cols != null) { - for (def in cols) { - println("The column name is ${def.name}") - println("The column type is ${def.type}") - } - } - } -} - -// snippet-start:[keyspace.kotlin.scenario.restore.table.main] -suspend fun restoreTable(keyspaceName: String?, utc: ZonedDateTime) { - // Create an aws.smithy.kotlin.runtime.time.Instant value. - val timeStamp = aws.smithy.kotlin.runtime.time.Instant(utc.toInstant()) - val restoreTableRequest = RestoreTableRequest { - restoreTimestamp = timeStamp - sourceTableName = "MovieKotlin" - targetKeyspaceName = keyspaceName - targetTableName = "MovieRestore" - sourceKeyspaceName = keyspaceName - } - - KeyspacesClient { region = "us-east-1" }.use { keyClient -> - val response = keyClient.restoreTable(restoreTableRequest) - println("The ARN of the restored table is ${response.restoredTableArn}") - } -} -// snippet-end:[keyspace.kotlin.scenario.restore.table.main] - -fun getWatchedData(session: CqlSession, keyspaceName: String) { - val resultSet = session.execute("SELECT * FROM \"$keyspaceName\".\"MovieKotlin\" WHERE watched = true ALLOW FILTERING;") - resultSet.forEach { item: Row -> - println("The Movie title is ${item.getString("title")}") - println("The Movie year is ${item.getInt("year")}") - println("The plot is ${item.getString("plot")}") - } -} - -fun updateRecord(session: CqlSession, keySpace: String, titleUpdate: String?, yearUpdate: Int) { - val sqlStatement = - "UPDATE \"$keySpace\".\"MovieKotlin\" SET watched=true WHERE title = :k0 AND year = :k1;" - val builder = BatchStatement.builder(DefaultBatchType.UNLOGGED) - builder.setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM) - val preparedStatement = session.prepare(sqlStatement) - builder.addStatement( - preparedStatement.boundStatementBuilder() - .setString("k0", titleUpdate) - .setInt("k1", yearUpdate) - .build() - ) - val batchStatement = builder.build() - session.execute(batchStatement) -} - -// snippet-start:[keyspace.kotlin.scenario.update.table.main] -suspend fun updateTable(keySpace: String?, tableNameVal: String?) { - val def = ColumnDefinition { - name = "watched" - type = "boolean" - } - - val tableRequest = UpdateTableRequest { - keyspaceName = keySpace - tableName = tableNameVal - addColumns = listOf(def) - } - - KeyspacesClient { region = "us-east-1" }.use { keyClient -> - keyClient.updateTable(tableRequest) - } -} -// snippet-end:[keyspace.kotlin.scenario.update.table.main] - -fun getSpecificMovie(session: CqlSession, keyspaceName: String) { - val resultSet = - session.execute("SELECT * FROM \"$keyspaceName\".\"MovieKotlin\" WHERE title = 'The Family' ALLOW FILTERING ;") - - resultSet.forEach { item: Row -> - println("The Movie title is ${item.getString("title")}") - println("The Movie year is ${item.getInt("year")}") - println("The plot is ${item.getString("plot")}") - } -} - -// Get records from the Movie table. -fun getMovieData(session: CqlSession, keyspaceName: String) { - val resultSet = session.execute("SELECT * FROM \"$keyspaceName\".\"MovieKotlin\";") - resultSet.forEach { item: Row -> - println("The Movie title is ${item.getString("title")}") - println("The Movie year is ${item.getInt("year")}") - println("The plot is ${item.getString("plot")}") - } -} - -// Load data into the table. -fun loadData(session: CqlSession, fileName: String, keySpace: String) { - val sqlStatement = - "INSERT INTO \"$keySpace\".\"MovieKotlin\" (title, year, plot) values (:k0, :k1, :k2)" - val parser = JsonFactory().createParser(File(fileName)) - val rootNode = ObjectMapper().readTree(parser) - val iter: Iterator = rootNode.iterator() - var currentNode: ObjectNode - - var t = 0 - while (iter.hasNext()) { - if (t == 50) { - break - } - - currentNode = iter.next() as ObjectNode - val year = currentNode.path("year").asInt() - val title = currentNode.path("title").asText() - val info = currentNode.path("info").toString() - - // Insert the data into the Amazon Keyspaces table. - val builder = BatchStatement.builder(DefaultBatchType.UNLOGGED) - builder.setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM) - val preparedStatement: PreparedStatement = session.prepare(sqlStatement) - builder.addStatement( - preparedStatement.boundStatementBuilder() - .setString("k0", title) - .setInt("k1", year) - .setString("k2", info) - .build() - ) - - val batchStatement = builder.build() - session.execute(batchStatement) - t++ - } -} - -// snippet-start:[keyspace.kotlin.scenario.list.tables.main] -suspend fun listTables(keyspaceNameVal: String?) { - val tablesRequest = ListTablesRequest { - keyspaceName = keyspaceNameVal - } - - KeyspacesClient { region = "us-east-1" }.use { keyClient -> - keyClient.listTablesPaginated(tablesRequest) - .transform { it.tables?.forEach { obj -> emit(obj) } } - .collect { obj -> - println( - " ARN: " + obj.resourceArn.toString() + - " Table name: " + obj.tableName - ) - } - } -} -// snippet-end:[keyspace.kotlin.scenario.list.tables.main] - -// snippet-start:[keyspace.kotlin.scenario.get.table.main] -suspend fun checkTable(keyspaceNameVal: String?, tableNameVal: String?) { - var tableStatus = false - var status: String - var response: GetTableResponse? = null - - val tableRequest = GetTableRequest { - keyspaceName = keyspaceNameVal - tableName = tableNameVal - } - KeyspacesClient { region = "us-east-1" }.use { keyClient -> - while (!tableStatus) { - response = keyClient.getTable(tableRequest) - status = response!!.status.toString() - println(". The table status is $status") - if (status.compareTo("ACTIVE") == 0) { - tableStatus = true - } - delay(500) - } - val cols: List? = response!!.schemaDefinition?.allColumns - if (cols != null) { - for (def in cols) { - println("The column name is ${def.name}") - println("The column type is ${def.type}") - } - } - } -} -// snippet-end:[keyspace.kotlin.scenario.get.table.main] - -// snippet-start:[keyspace.kotlin.scenario.create.table.main] -suspend fun createTable(keySpaceVal: String?, tableNameVal: String?) { - // Set the columns. - val defTitle = ColumnDefinition { - name = "title" - type = "text" - } - - val defYear = ColumnDefinition { - name = "year" - type = "int" - } - - val defReleaseDate = ColumnDefinition { - name = "release_date" - type = "timestamp" - } - - val defPlot = ColumnDefinition { - name = "plot" - type = "text" - } - - val colList = ArrayList() - colList.add(defTitle) - colList.add(defYear) - colList.add(defReleaseDate) - colList.add(defPlot) - - // Set the keys. - val yearKey = PartitionKey { - name = "year" - } - - val titleKey = PartitionKey { - name = "title" - } - - val keyList = ArrayList() - keyList.add(yearKey) - keyList.add(titleKey) - - val schemaDefinitionOb = SchemaDefinition { - partitionKeys = keyList - allColumns = colList - } - - val timeRecovery = PointInTimeRecovery { - status = PointInTimeRecoveryStatus.Enabled - } - - val tableRequest = CreateTableRequest { - keyspaceName = keySpaceVal - tableName = tableNameVal - schemaDefinition = schemaDefinitionOb - pointInTimeRecovery = timeRecovery - } - - KeyspacesClient { region = "us-east-1" }.use { keyClient -> - val response = keyClient.createTable(tableRequest) - println("The table ARN is ${response.resourceArn}") - } -} -// snippet-end:[keyspace.kotlin.scenario.create.table.main] - -// snippet-start:[keyspace.kotlin.scenario.list.keyspaces.main] -suspend fun listKeyspacesPaginator() { - KeyspacesClient { region = "us-east-1" }.use { keyClient -> - keyClient.listKeyspacesPaginated(ListKeyspacesRequest {}) - .transform { it.keyspaces?.forEach { obj -> emit(obj) } } - .collect { obj -> - println("Name: ${obj.keyspaceName}") - } - } -} -// snippet-end:[keyspace.kotlin.scenario.list.keyspaces.main] - -// snippet-start:[keyspace.kotlin.scenario.get.keyspace.main] -suspend fun checkKeyspaceExistence(keyspaceNameVal: String?) { - val keyspaceRequest = GetKeyspaceRequest { - keyspaceName = keyspaceNameVal - } - KeyspacesClient { region = "us-east-1" }.use { keyClient -> - val response: GetKeyspaceResponse = keyClient.getKeyspace(keyspaceRequest) - val name = response.keyspaceName - println("The $name KeySpace is ready") - } -} -// snippet-end:[keyspace.kotlin.scenario.get.keyspace.main] - -// snippet-start:[keyspace.kotlin.scenario.create.keyspace.main] -suspend fun createKeySpace(keyspaceNameVal: String) { - val keyspaceRequest = CreateKeyspaceRequest { - keyspaceName = keyspaceNameVal - } - - KeyspacesClient { region = "us-east-1" }.use { keyClient -> - val response = keyClient.createKeyspace(keyspaceRequest) - println("The ARN of the KeySpace is ${response.resourceArn}") - } -} -// snippet-end:[keyspace.kotlin.scenario.create.keyspace.main] -// snippet-end:[keyspace.kotlin.scenario.main] +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package com.example.keyspace + +import aws.sdk.kotlin.services.keyspaces.KeyspacesClient +import aws.sdk.kotlin.services.keyspaces.model.ColumnDefinition +import aws.sdk.kotlin.services.keyspaces.model.CreateKeyspaceRequest +import aws.sdk.kotlin.services.keyspaces.model.CreateTableRequest +import aws.sdk.kotlin.services.keyspaces.model.DeleteKeyspaceRequest +import aws.sdk.kotlin.services.keyspaces.model.DeleteTableRequest +import aws.sdk.kotlin.services.keyspaces.model.GetKeyspaceRequest +import aws.sdk.kotlin.services.keyspaces.model.GetKeyspaceResponse +import aws.sdk.kotlin.services.keyspaces.model.GetTableRequest +import aws.sdk.kotlin.services.keyspaces.model.GetTableResponse +import aws.sdk.kotlin.services.keyspaces.model.ListKeyspacesRequest +import aws.sdk.kotlin.services.keyspaces.model.ListTablesRequest +import aws.sdk.kotlin.services.keyspaces.model.PartitionKey +import aws.sdk.kotlin.services.keyspaces.model.PointInTimeRecovery +import aws.sdk.kotlin.services.keyspaces.model.PointInTimeRecoveryStatus +import aws.sdk.kotlin.services.keyspaces.model.ResourceNotFoundException +import aws.sdk.kotlin.services.keyspaces.model.RestoreTableRequest +import aws.sdk.kotlin.services.keyspaces.model.SchemaDefinition +import aws.sdk.kotlin.services.keyspaces.model.UpdateTableRequest +import aws.sdk.kotlin.services.keyspaces.paginators.listKeyspacesPaginated +import aws.sdk.kotlin.services.keyspaces.paginators.listTablesPaginated +import com.datastax.oss.driver.api.core.ConsistencyLevel +import com.datastax.oss.driver.api.core.CqlSession +import com.datastax.oss.driver.api.core.config.DriverConfigLoader +import com.datastax.oss.driver.api.core.cql.BatchStatement +import com.datastax.oss.driver.api.core.cql.DefaultBatchType +import com.datastax.oss.driver.api.core.cql.PreparedStatement +import com.datastax.oss.driver.api.core.cql.Row +import com.fasterxml.jackson.core.JsonFactory +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.databind.node.ObjectNode +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.transform +import java.io.File +import java.time.ZoneOffset +import java.time.ZonedDateTime +import java.util.Date + +// snippet-start:[keyspace.kotlin.scenario.main] + +/** + Before running this Kotlin code example, set up your development environment, including your credentials. + + For more information, see the following documentation topic: + + https://docs.aws.amazon.com/sdk-for-kotlin/latest/developer-guide/setup.html + + This example uses a secure file format to hold certificate information for + Kotlin applications. This is required to make a connection to Amazon Keyspaces. + For more information, see the following documentation topic: + + https://docs.aws.amazon.com/keyspaces/latest/devguide/using_java_driver.html + + This Kotlin example performs the following tasks: + + 1. Create a keyspace. + 2. Check for keyspace existence. + 3. List keyspaces using a paginator. + 4. Create a table with a simple movie data schema and enable point-in-time recovery. + 5. Check for the table to be in an Active state. + 6. List all tables in the keyspace. + 7. Use a Cassandra driver to insert some records into the Movie table. + 8. Get all records from the Movie table. + 9. Get a specific Movie. + 10. Get a UTC timestamp for the current time. + 11. Update the table schema to add a ‘watched’ Boolean column. + 12. Update an item as watched. + 13. Query for items with watched = True. + 14. Restore the table back to the previous state using the timestamp. + 15. Check for completion of the restore action. + 16. Delete the table. + 17. Confirm that both tables are deleted. + 18. Delete the keyspace. + */ + +/* + Usage: + fileName - The name of the JSON file that contains movie data. (Get this file from the GitHub repo at resources/sample_file.) + keyspaceName - The name of the keyspace to create. + */ +val DASHES: String = String(CharArray(80)).replace("\u0000", "-") + +suspend fun main() { + val fileName = "" + val keyspaceName = "" + val titleUpdate = "The Family" + val yearUpdate = 2013 + val tableName = "MovieKotlin" + val tableNameRestore = "MovieRestore" + + val loader = DriverConfigLoader.fromClasspath("application.conf") + val session = + CqlSession + .builder() + .withConfigLoader(loader) + .build() + + println(DASHES) + println("Welcome to the Amazon Keyspaces example scenario.") + println(DASHES) + + println(DASHES) + println("1. Create a keyspace.") + createKeySpace(keyspaceName) + println(DASHES) + + println(DASHES) + delay(5000) + println("2. Check for keyspace existence.") + checkKeyspaceExistence(keyspaceName) + println(DASHES) + + println(DASHES) + println("3. List keyspaces using a paginator.") + listKeyspacesPaginator() + println(DASHES) + + println(DASHES) + println("4. Create a table with a simple movie data schema and enable point-in-time recovery.") + createTable(keyspaceName, tableName) + println(DASHES) + + println(DASHES) + println("5. Check for the table to be in an Active state.") + delay(6000) + checkTable(keyspaceName, tableName) + println(DASHES) + + println(DASHES) + println("6. List all tables in the keyspace.") + listTables(keyspaceName) + println(DASHES) + + println(DASHES) + println("7. Use a Cassandra driver to insert some records into the Movie table.") + delay(6000) + loadData(session, fileName, keyspaceName) + println(DASHES) + + println(DASHES) + println("8. Get all records from the Movie table.") + getMovieData(session, keyspaceName) + println(DASHES) + + println(DASHES) + println("9. Get a specific Movie.") + getSpecificMovie(session, keyspaceName) + println(DASHES) + + println(DASHES) + println("10. Get a UTC timestamp for the current time.") + val utc = ZonedDateTime.now(ZoneOffset.UTC) + println("DATETIME = ${Date.from(utc.toInstant())}") + println(DASHES) + + println(DASHES) + println("11. Update the table schema to add a watched Boolean column.") + updateTable(keyspaceName, tableName) + println(DASHES) + + println(DASHES) + println("12. Update an item as watched.") + delay(10000) // Wait 10 seconds for the update. + updateRecord(session, keyspaceName, titleUpdate, yearUpdate) + println(DASHES) + + println(DASHES) + println("13. Query for items with watched = True.") + getWatchedData(session, keyspaceName) + println(DASHES) + + println(DASHES) + println("14. Restore the table back to the previous state using the timestamp.") + println("Note that the restore operation can take up to 20 minutes.") + restoreTable(keyspaceName, utc) + println(DASHES) + + println(DASHES) + println("15. Check for completion of the restore action.") + delay(5000) + checkRestoredTable(keyspaceName, "MovieRestore") + println(DASHES) + + println(DASHES) + println("16. Delete both tables.") + deleteTable(keyspaceName, tableName) + deleteTable(keyspaceName, tableNameRestore) + println(DASHES) + + println(DASHES) + println("17. Confirm that both tables are deleted.") + checkTableDelete(keyspaceName, tableName) + checkTableDelete(keyspaceName, tableNameRestore) + println(DASHES) + + println(DASHES) + println("18. Delete the keyspace.") + deleteKeyspace(keyspaceName) + println(DASHES) + + println(DASHES) + println("The scenario has completed successfully.") + println(DASHES) +} + +// snippet-start:[keyspace.kotlin.scenario.delete.keyspace.main] +suspend fun deleteKeyspace(keyspaceNameVal: String?) { + val deleteKeyspaceRequest = + DeleteKeyspaceRequest { + keyspaceName = keyspaceNameVal + } + + KeyspacesClient { region = "us-east-1" }.use { keyClient -> + keyClient.deleteKeyspace(deleteKeyspaceRequest) + } +} +// snippet-end:[keyspace.kotlin.scenario.delete.keyspace.main] + +suspend fun checkTableDelete( + keyspaceNameVal: String?, + tableNameVal: String? +) { + var status: String + var response: GetTableResponse + val tableRequest = + GetTableRequest { + keyspaceName = keyspaceNameVal + tableName = tableNameVal + } + + try { + KeyspacesClient { region = "us-east-1" }.use { keyClient -> + // Keep looping until the table cannot be found and a ResourceNotFoundException is thrown. + while (true) { + response = keyClient.getTable(tableRequest) + status = response.status.toString() + println(". The table status is $status") + delay(500) + } + } + } catch (e: ResourceNotFoundException) { + println(e.message) + } + println("The table is deleted") +} + +// snippet-start:[keyspace.kotlin.scenario.delete.table.main] +suspend fun deleteTable( + keyspaceNameVal: String?, + tableNameVal: String? +) { + val tableRequest = + DeleteTableRequest { + keyspaceName = keyspaceNameVal + tableName = tableNameVal + } + + KeyspacesClient { region = "us-east-1" }.use { keyClient -> + keyClient.deleteTable(tableRequest) + } +} +// snippet-end:[keyspace.kotlin.scenario.delete.table.main] + +suspend fun checkRestoredTable( + keyspaceNameVal: String?, + tableNameVal: String? +) { + var tableStatus = false + var status: String + var response: GetTableResponse? = null + + val tableRequest = + GetTableRequest { + keyspaceName = keyspaceNameVal + tableName = tableNameVal + } + + KeyspacesClient { region = "us-east-1" }.use { keyClient -> + while (!tableStatus) { + response = keyClient.getTable(tableRequest) + status = response!!.status.toString() + println("The table status is $status") + + if (status.compareTo("ACTIVE") == 0) { + tableStatus = true + } + delay(500) + } + + val cols = response!!.schemaDefinition?.allColumns + if (cols != null) { + for (def in cols) { + println("The column name is ${def.name}") + println("The column type is ${def.type}") + } + } + } +} + +// snippet-start:[keyspace.kotlin.scenario.restore.table.main] +suspend fun restoreTable( + keyspaceName: String?, + utc: ZonedDateTime +) { + // Create an aws.smithy.kotlin.runtime.time.Instant value. + val timeStamp = + aws.smithy.kotlin.runtime.time + .Instant(utc.toInstant()) + val restoreTableRequest = + RestoreTableRequest { + restoreTimestamp = timeStamp + sourceTableName = "MovieKotlin" + targetKeyspaceName = keyspaceName + targetTableName = "MovieRestore" + sourceKeyspaceName = keyspaceName + } + + KeyspacesClient { region = "us-east-1" }.use { keyClient -> + val response = keyClient.restoreTable(restoreTableRequest) + println("The ARN of the restored table is ${response.restoredTableArn}") + } +} +// snippet-end:[keyspace.kotlin.scenario.restore.table.main] + +fun getWatchedData( + session: CqlSession, + keyspaceName: String +) { + val resultSet = session.execute("SELECT * FROM \"$keyspaceName\".\"MovieKotlin\" WHERE watched = true ALLOW FILTERING;") + resultSet.forEach { item: Row -> + println("The Movie title is ${item.getString("title")}") + println("The Movie year is ${item.getInt("year")}") + println("The plot is ${item.getString("plot")}") + } +} + +fun updateRecord( + session: CqlSession, + keySpace: String, + titleUpdate: String?, + yearUpdate: Int +) { + val sqlStatement = + "UPDATE \"$keySpace\".\"MovieKotlin\" SET watched=true WHERE title = :k0 AND year = :k1;" + val builder = BatchStatement.builder(DefaultBatchType.UNLOGGED) + builder.setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM) + val preparedStatement = session.prepare(sqlStatement) + builder.addStatement( + preparedStatement + .boundStatementBuilder() + .setString("k0", titleUpdate) + .setInt("k1", yearUpdate) + .build(), + ) + val batchStatement = builder.build() + session.execute(batchStatement) +} + +// snippet-start:[keyspace.kotlin.scenario.update.table.main] +suspend fun updateTable( + keySpace: String?, + tableNameVal: String? +) { + val def = + ColumnDefinition { + name = "watched" + type = "boolean" + } + + val tableRequest = + UpdateTableRequest { + keyspaceName = keySpace + tableName = tableNameVal + addColumns = listOf(def) + } + + KeyspacesClient { region = "us-east-1" }.use { keyClient -> + keyClient.updateTable(tableRequest) + } +} +// snippet-end:[keyspace.kotlin.scenario.update.table.main] + +fun getSpecificMovie( + session: CqlSession, + keyspaceName: String +) { + val resultSet = + session.execute("SELECT * FROM \"$keyspaceName\".\"MovieKotlin\" WHERE title = 'The Family' ALLOW FILTERING ;") + + resultSet.forEach { item: Row -> + println("The Movie title is ${item.getString("title")}") + println("The Movie year is ${item.getInt("year")}") + println("The plot is ${item.getString("plot")}") + } +} + +// Get records from the Movie table. +fun getMovieData( + session: CqlSession, + keyspaceName: String +) { + val resultSet = session.execute("SELECT * FROM \"$keyspaceName\".\"MovieKotlin\";") + resultSet.forEach { item: Row -> + println("The Movie title is ${item.getString("title")}") + println("The Movie year is ${item.getInt("year")}") + println("The plot is ${item.getString("plot")}") + } +} + +// Load data into the table. +fun loadData( + session: CqlSession, + fileName: String, + keySpace: String +) { + val sqlStatement = + "INSERT INTO \"$keySpace\".\"MovieKotlin\" (title, year, plot) values (:k0, :k1, :k2)" + val parser = JsonFactory().createParser(File(fileName)) + val rootNode = ObjectMapper().readTree(parser) + val iter: Iterator = rootNode.iterator() + var currentNode: ObjectNode + + var t = 0 + while (iter.hasNext()) { + if (t == 50) { + break + } + + currentNode = iter.next() as ObjectNode + val year = currentNode.path("year").asInt() + val title = currentNode.path("title").asText() + val info = currentNode.path("info").toString() + + // Insert the data into the Amazon Keyspaces table. + val builder = BatchStatement.builder(DefaultBatchType.UNLOGGED) + builder.setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM) + val preparedStatement: PreparedStatement = session.prepare(sqlStatement) + builder.addStatement( + preparedStatement + .boundStatementBuilder() + .setString("k0", title) + .setInt("k1", year) + .setString("k2", info) + .build(), + ) + + val batchStatement = builder.build() + session.execute(batchStatement) + t++ + } +} + +// snippet-start:[keyspace.kotlin.scenario.list.tables.main] +suspend fun listTables(keyspaceNameVal: String?) { + val tablesRequest = + ListTablesRequest { + keyspaceName = keyspaceNameVal + } + + KeyspacesClient { region = "us-east-1" }.use { keyClient -> + keyClient + .listTablesPaginated(tablesRequest) + .transform { it.tables?.forEach { obj -> emit(obj) } } + .collect { obj -> + println( + " ARN: " + obj.resourceArn.toString() + + " Table name: " + obj.tableName, + ) + } + } +} +// snippet-end:[keyspace.kotlin.scenario.list.tables.main] + +// snippet-start:[keyspace.kotlin.scenario.get.table.main] +suspend fun checkTable( + keyspaceNameVal: String?, + tableNameVal: String? +) { + var tableStatus = false + var status: String + var response: GetTableResponse? = null + + val tableRequest = + GetTableRequest { + keyspaceName = keyspaceNameVal + tableName = tableNameVal + } + KeyspacesClient { region = "us-east-1" }.use { keyClient -> + while (!tableStatus) { + response = keyClient.getTable(tableRequest) + status = response!!.status.toString() + println(". The table status is $status") + if (status.compareTo("ACTIVE") == 0) { + tableStatus = true + } + delay(500) + } + val cols: List? = response!!.schemaDefinition?.allColumns + if (cols != null) { + for (def in cols) { + println("The column name is ${def.name}") + println("The column type is ${def.type}") + } + } + } +} +// snippet-end:[keyspace.kotlin.scenario.get.table.main] + +// snippet-start:[keyspace.kotlin.scenario.create.table.main] +suspend fun createTable( + keySpaceVal: String?, + tableNameVal: String? +) { + // Set the columns. + val defTitle = + ColumnDefinition { + name = "title" + type = "text" + } + + val defYear = + ColumnDefinition { + name = "year" + type = "int" + } + + val defReleaseDate = + ColumnDefinition { + name = "release_date" + type = "timestamp" + } + + val defPlot = + ColumnDefinition { + name = "plot" + type = "text" + } + + val colList = ArrayList() + colList.add(defTitle) + colList.add(defYear) + colList.add(defReleaseDate) + colList.add(defPlot) + + // Set the keys. + val yearKey = + PartitionKey { + name = "year" + } + + val titleKey = + PartitionKey { + name = "title" + } + + val keyList = ArrayList() + keyList.add(yearKey) + keyList.add(titleKey) + + val schemaDefinitionOb = + SchemaDefinition { + partitionKeys = keyList + allColumns = colList + } + + val timeRecovery = + PointInTimeRecovery { + status = PointInTimeRecoveryStatus.Enabled + } + + val tableRequest = + CreateTableRequest { + keyspaceName = keySpaceVal + tableName = tableNameVal + schemaDefinition = schemaDefinitionOb + pointInTimeRecovery = timeRecovery + } + + KeyspacesClient { region = "us-east-1" }.use { keyClient -> + val response = keyClient.createTable(tableRequest) + println("The table ARN is ${response.resourceArn}") + } +} +// snippet-end:[keyspace.kotlin.scenario.create.table.main] + +// snippet-start:[keyspace.kotlin.scenario.list.keyspaces.main] +suspend fun listKeyspacesPaginator() { + KeyspacesClient { region = "us-east-1" }.use { keyClient -> + keyClient + .listKeyspacesPaginated(ListKeyspacesRequest {}) + .transform { it.keyspaces?.forEach { obj -> emit(obj) } } + .collect { obj -> + println("Name: ${obj.keyspaceName}") + } + } +} +// snippet-end:[keyspace.kotlin.scenario.list.keyspaces.main] + +// snippet-start:[keyspace.kotlin.scenario.get.keyspace.main] +suspend fun checkKeyspaceExistence(keyspaceNameVal: String?) { + val keyspaceRequest = + GetKeyspaceRequest { + keyspaceName = keyspaceNameVal + } + KeyspacesClient { region = "us-east-1" }.use { keyClient -> + val response: GetKeyspaceResponse = keyClient.getKeyspace(keyspaceRequest) + val name = response.keyspaceName + println("The $name KeySpace is ready") + } +} +// snippet-end:[keyspace.kotlin.scenario.get.keyspace.main] + +// snippet-start:[keyspace.kotlin.scenario.create.keyspace.main] +suspend fun createKeySpace(keyspaceNameVal: String) { + val keyspaceRequest = + CreateKeyspaceRequest { + keyspaceName = keyspaceNameVal + } + + KeyspacesClient { region = "us-east-1" }.use { keyClient -> + val response = keyClient.createKeyspace(keyspaceRequest) + println("The ARN of the KeySpace is ${response.resourceArn}") + } +} +// snippet-end:[keyspace.kotlin.scenario.create.keyspace.main] +// snippet-end:[keyspace.kotlin.scenario.main] diff --git a/kotlin/services/keyspaces/src/test/kotlin/KeyspaceTest.kt b/kotlin/services/keyspaces/src/test/kotlin/KeyspaceTest.kt index 69bbb88cb76..fc4a4047bd0 100644 --- a/kotlin/services/keyspaces/src/test/kotlin/KeyspaceTest.kt +++ b/kotlin/services/keyspaces/src/test/kotlin/KeyspaceTest.kt @@ -12,10 +12,10 @@ import org.junit.jupiter.api.TestMethodOrder @TestInstance(TestInstance.Lifecycle.PER_CLASS) @TestMethodOrder(MethodOrderer.OrderAnnotation::class) class KeyspaceTest { - @Test @Order(1) - fun KeyspaceTest() = runBlocking { - listKeyspaces() - } + fun keyspaceTest() = + runBlocking { + listKeyspaces() + } }