diff --git a/build.gradle b/build.gradle index e81d2b5e7..45ec0e134 100644 --- a/build.gradle +++ b/build.gradle @@ -178,6 +178,37 @@ dependencies { implementation("com.fasterxml.jackson.core:jackson-annotations:${versions.jackson}") implementation("com.fasterxml.jackson.core:jackson-databind:${versions.jackson_databind}") + // DynamoDB + implementation("software.amazon.awssdk:sdk-core:2.25.17") + implementation("software.amazon.awssdk:aws-core:2.25.17") + implementation "software.amazon.awssdk:aws-json-protocol:2.25.17" + implementation("software.amazon.awssdk:auth:2.25.17") + implementation("software.amazon.awssdk:checksums:2.25.17") + implementation("software.amazon.awssdk:checksums-spi:2.25.17") + implementation("software.amazon.awssdk:dynamodb:2.25.17") + implementation("software.amazon.awssdk:endpoints-spi:2.25.17") + implementation("software.amazon.awssdk:http-auth-aws:2.25.17") + implementation("software.amazon.awssdk:http-auth-spi:2.25.17") + implementation("software.amazon.awssdk:http-client-spi:2.25.17") + implementation("software.amazon.awssdk:identity-spi:2.25.17") + implementation "software.amazon.awssdk:json-utils:2.25.17" + implementation "software.amazon.awssdk:metrics-spi:2.25.17" + implementation("software.amazon.awssdk:profiles:2.25.17") + implementation "software.amazon.awssdk:protocol-core:2.25.17" + implementation("software.amazon.awssdk:regions:2.25.17") + implementation "software.amazon.awssdk:third-party-jackson-core:2.25.17" + implementation("software.amazon.awssdk:url-connection-client:2.25.17") + implementation("software.amazon.awssdk:utils:2.25.17") + /* Possibly needed later, keeping for reference + implementation "software.amazon.awssdk:annotations:2.25.17" + implementation "software.amazon.awssdk:apache-client:2.25.17" + implementation "software.amazon.awssdk:signer:2.25.17" + implementation "software.amazon.awssdk:aws-xml-protocol:2.25.17" + implementation "software.amazon.awssdk:aws-query-protocol:2.25.17" + implementation "software.amazon.awssdk:sts:2.25.17" + implementation "software.amazon.awssdk:netty-nio-client:2.25.17" + */ + // ZipArchive dependencies used for integration tests zipArchive group: 'org.opensearch.plugin', name:'opensearch-ml-plugin', version: "${opensearch_build}" secureIntegTestPluginArchive group: 'org.opensearch.plugin', name:'opensearch-security', version: "${opensearch_build}" diff --git a/src/main/java/org/opensearch/flowframework/indices/DynamoDBDemo.java b/src/main/java/org/opensearch/flowframework/indices/DynamoDBDemo.java new file mode 100644 index 000000000..145ba9964 --- /dev/null +++ b/src/main/java/org/opensearch/flowframework/indices/DynamoDBDemo.java @@ -0,0 +1,236 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ +package org.opensearch.flowframework.indices; + +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; +import software.amazon.awssdk.core.waiters.WaiterResponse; +import software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.dynamodb.DynamoDbClient; +import software.amazon.awssdk.services.dynamodb.model.AttributeDefinition; +import software.amazon.awssdk.services.dynamodb.model.AttributeValue; +import software.amazon.awssdk.services.dynamodb.model.CreateTableRequest; +import software.amazon.awssdk.services.dynamodb.model.CreateTableResponse; +import software.amazon.awssdk.services.dynamodb.model.DeleteItemRequest; +import software.amazon.awssdk.services.dynamodb.model.DescribeTableRequest; +import software.amazon.awssdk.services.dynamodb.model.DescribeTableResponse; +import software.amazon.awssdk.services.dynamodb.model.DynamoDbException; +import software.amazon.awssdk.services.dynamodb.model.GetItemRequest; +import software.amazon.awssdk.services.dynamodb.model.KeySchemaElement; +import software.amazon.awssdk.services.dynamodb.model.KeyType; +import software.amazon.awssdk.services.dynamodb.model.ListTablesResponse; +import software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughput; +import software.amazon.awssdk.services.dynamodb.model.PutItemRequest; +import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; +import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType; +import software.amazon.awssdk.services.dynamodb.waiters.DynamoDbWaiter; + +import java.net.URI; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +public class DynamoDBDemo { + + public static String createTable(DynamoDbClient ddb, String tableName, String key) { + + DynamoDbWaiter dbWaiter = ddb.waiter(); + CreateTableRequest request = CreateTableRequest.builder() + .attributeDefinitions(AttributeDefinition.builder().attributeName(key).attributeType(ScalarAttributeType.S).build()) + .keySchema(KeySchemaElement.builder().attributeName(key).keyType(KeyType.HASH).build()) + .provisionedThroughput( + ProvisionedThroughput.builder().readCapacityUnits(Long.valueOf(5)).writeCapacityUnits(Long.valueOf(5)).build() + ) + .tableName(tableName) + .build(); + + String newTable = ""; + try { + CreateTableResponse response = ddb.createTable(request); + DescribeTableRequest tableRequest = DescribeTableRequest.builder().tableName(tableName).build(); + + // Wait until the Amazon DynamoDB table is created + WaiterResponse waiterResponse = dbWaiter.waitUntilTableExists(tableRequest); + waiterResponse.matched().response().ifPresent(System.out::println); + + newTable = response.tableDescription().tableName(); + return newTable; + + } catch (DynamoDbException e) { + System.err.println(e.getMessage()); + System.exit(1); + } + return ""; + } + + public static void putItemInTable( + DynamoDbClient ddb, + String tableName, + String key, + String keyVal, + String albumTitle, + String albumTitleValue, + String awards, + String awardVal, + String songTitle, + String songTitleVal + ) { + + HashMap itemValues = new HashMap(); + + // Add all content to the table + itemValues.put(key, AttributeValue.builder().s(keyVal).build()); + itemValues.put(songTitle, AttributeValue.builder().s(songTitleVal).build()); + itemValues.put(albumTitle, AttributeValue.builder().s(albumTitleValue).build()); + itemValues.put(awards, AttributeValue.builder().s(awardVal).build()); + + PutItemRequest request = PutItemRequest.builder().tableName(tableName).item(itemValues).build(); + + try { + ddb.putItem(request); + } catch (ResourceNotFoundException e) { + System.err.format("Error: The Amazon DynamoDB table \"%s\" can't be found.\n", tableName); + System.err.println("Be sure that it exists and that you've typed its name correctly!"); + System.exit(1); + } catch (DynamoDbException e) { + System.err.println(e.getMessage()); + System.exit(1); + } + } + + public static void getDynamoDBItem(DynamoDbClient ddb, String tableName, String key, String keyVal) { + + HashMap keyToGet = new HashMap(); + + keyToGet.put(key, AttributeValue.builder().s(keyVal).build()); + + GetItemRequest request = GetItemRequest.builder().key(keyToGet).tableName(tableName).consistentRead(true).build(); + + try { + Map returnedItem = ddb.getItem(request).item(); + + if (returnedItem.size() != 0) { + Set keys = returnedItem.keySet(); + for (String key1 : keys) { + System.out.format("%s: %s\n", key1, returnedItem.get(key1).s()); + } + } else { + System.out.format("No item found with the key: %s!\n", keyToGet.get(key).s()); + } + } catch (DynamoDbException e) { + System.err.println(e.getMessage()); + System.exit(1); + } + } + + public static void deleteDynamoDBItem(DynamoDbClient ddb, String tableName, String key, String keyVal) { + + HashMap keyToGet = new HashMap(); + + keyToGet.put(key, AttributeValue.builder().s(keyVal).build()); + + DeleteItemRequest deleteReq = DeleteItemRequest.builder().tableName(tableName).key(keyToGet).build(); + + try { + ddb.deleteItem(deleteReq); + } catch (DynamoDbException e) { + System.err.println(e.getMessage()); + System.exit(1); + } + } + + public static void main(String[] args) { + + try { + String port = "8000"; + String uri = "http://localhost:" + port; + + // Create a client and connect to DynamoDB Local + // Note: This is a dummy key and secret and AWS_ACCESS_KEY_ID can contain only letters (A–Z, a–z) and numbers (0–9). + DynamoDbClient ddbClient = DynamoDbClient.builder() + .endpointOverride(URI.create(uri)) + .httpClient(UrlConnectionHttpClient.builder().build()) + .region(Region.US_WEST_2) + .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create("dummyKey", "dummySecret"))) + .build(); + + String tableName = "Music"; + String keyName = "Artist"; + + // Create a table in DynamoDB Local with table name Music and partition key Artist + // Understanding core components of DynamoDB: + // https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html + createTable(ddbClient, tableName, keyName); + + // List all the tables in DynamoDB Local + + System.out.println("Listing tables in DynamoDB Local..."); + System.out.println("-------------------------------"); + ListTablesResponse listTablesResponse = ddbClient.listTables(); + System.out.println(listTablesResponse.tableNames()); + + String key1 = "No One you know"; + String key2 = "The Beatles"; + + // Insert data into the table + System.out.println(); + System.out.println("Inserting data into the table:" + tableName); + System.out.println(); + putItemInTable( + ddbClient, + tableName, + keyName, + key1, + "albumTitle", + "The Colour And The Shape", + "awards", + "awardVal", + "songTitle", + "songTitleVal" + ); + putItemInTable( + ddbClient, + tableName, + keyName, + key2, + "albumTitle", + "Let It Be", + "awards", + "awardVal", + "songTitle", + "songTitleVal" + ); + + // Get data from the table + System.out.println("Getting Item from the table for key: " + key1); + System.out.println("-------------------------------"); + getDynamoDBItem(ddbClient, tableName, keyName, key1); + + System.out.println(); + + System.out.println("Getting Item from the table for key: " + key2); + System.out.println("-------------------------------"); + getDynamoDBItem(ddbClient, tableName, keyName, key2); + + System.out.println(); + System.out.println("Deleting Item with key: " + key1); + System.out.println(); + + deleteDynamoDBItem(ddbClient, tableName, keyName, key1); + + System.out.println("Getting Item for key: " + key1); + System.out.println("-------------------------------"); + getDynamoDBItem(ddbClient, tableName, keyName, key1); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } +}