<commit_before>package org.sagebionetworks.bridge.dynamodb;

import java.io.IOException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.sagebionetworks.bridge.config.BridgeConfig;
import org.sagebionetworks.bridge.config.BridgeConfigFactory;
import org.sagebionetworks.bridge.config.Environment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBIndexRangeKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBRangeKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;
import com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
import com.amazonaws.services.dynamodbv2.model.DescribeTableRequest;
import com.amazonaws.services.dynamodbv2.model.DescribeTableResult;
import com.amazonaws.services.dynamodbv2.model.GlobalSecondaryIndexDescription;
import com.amazonaws.services.dynamodbv2.model.KeySchemaElement;
import com.amazonaws.services.dynamodbv2.model.KeyType;
import com.amazonaws.services.dynamodbv2.model.ListTablesResult;
import com.amazonaws.services.dynamodbv2.model.LocalSecondaryIndex;
import com.amazonaws.services.dynamodbv2.model.LocalSecondaryIndexDescription;
import com.amazonaws.services.dynamodbv2.model.Projection;
import com.amazonaws.services.dynamodbv2.model.ProjectionType;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughputDescription;
import com.amazonaws.services.dynamodbv2.model.ResourceNotFoundException;
import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType;
import com.amazonaws.services.dynamodbv2.model.TableDescription;
import com.amazonaws.services.dynamodbv2.model.TableStatus;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.ClassPath;
import com.google.common.reflect.ClassPath.ClassInfo;

public class DynamoInitializer {

    private static Logger logger = LoggerFactory.getLogger(DynamoInitializer.class);

    // DynamoDB Free tier
    private static final Long READ_CAPACITY = Long.valueOf(10);
    private static final Long WRITE_CAPACITY = Long.valueOf(5);

    private static final BridgeConfig CONFIG = BridgeConfigFactory.getConfig();

    private static final AmazonDynamoDB DYNAMO;
    static {
        String awsKey = CONFIG.getProperty("aws.key");
        String secretKey = CONFIG.getProperty("aws.secret.key");
        DYNAMO = new AmazonDynamoDBClient(new BasicAWSCredentials(awsKey, secretKey));
    }

    /**
     * Creates DynamoDB tables, if they do not exist yet, from the annotated types.
     * in the package "org.sagebionetworks.bridge.dynamodb". Throws an error
     * if the table exists but the schema (hash key, range key, and secondary indices)
     * does not match.
     */
    public static void init(String dynamoPackage) {
        beforeInit();
        List<TableDescription> tables = getAnnotatedTables(dynamoPackage);
        initTables(tables);
    }

    /**
     * For phasing out obsolete schemas.
     */
    static void beforeInit() {
        deleteTable("HealthCodeSalt");
    }

    static void deleteTable(String table) {
        table = getTableName(table);
        try {
            logger.info("Deleting table " + table);
            DYNAMO.deleteTable(table);
            logger.info("Table " + table + " deleted.");
        } catch(ResourceNotFoundException e) {
            logger.warn("Table " + table + " does not exist.");
        }
    }

    /**
     * Prefix the table name with '{env}-' and '{user}-'.
     */
    static String getTableName(String table) {
        Environment env = CONFIG.getEnvironment();
        return env.getEnvName() + "-" + CONFIG.getUser() + "-" + table;
    }

    /**
     * Converts the annotated DynamoDBTable types to a list of TableDescription.
     */
    static List<TableDescription> getAnnotatedTables(final String dynamoPackage) {
        List<TableDescription> tables = new ArrayList<TableDescription>();
        List<Class<?>> classes = loadDynamoTableClasses(dynamoPackage);
        for (Class<?> clazz : classes) {
            final List<KeySchemaElement> keySchema = new ArrayList<KeySchemaElement>();<commit_msg>Make deleting table more robust.<commit_after>package org.sagebionetworks.bridge.dynamodb;

import java.io.IOException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.sagebionetworks.bridge.config.BridgeConfig;
import org.sagebionetworks.bridge.config.BridgeConfigFactory;
import org.sagebionetworks.bridge.config.Environment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBIndexRangeKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBRangeKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;
import com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
import com.amazonaws.services.dynamodbv2.model.DescribeTableRequest;
import com.amazonaws.services.dynamodbv2.model.DescribeTableResult;
import com.amazonaws.services.dynamodbv2.model.GlobalSecondaryIndexDescription;
import com.amazonaws.services.dynamodbv2.model.KeySchemaElement;
import com.amazonaws.services.dynamodbv2.model.KeyType;
import com.amazonaws.services.dynamodbv2.model.ListTablesResult;
import com.amazonaws.services.dynamodbv2.model.LocalSecondaryIndex;
import com.amazonaws.services.dynamodbv2.model.LocalSecondaryIndexDescription;
import com.amazonaws.services.dynamodbv2.model.Projection;
import com.amazonaws.services.dynamodbv2.model.ProjectionType;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughputDescription;
import com.amazonaws.services.dynamodbv2.model.ResourceNotFoundException;
import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType;
import com.amazonaws.services.dynamodbv2.model.TableDescription;
import com.amazonaws.services.dynamodbv2.model.TableStatus;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.ClassPath;
import com.google.common.reflect.ClassPath.ClassInfo;

public class DynamoInitializer {

    private static Logger logger = LoggerFactory.getLogger(DynamoInitializer.class);

    // DynamoDB Free tier
    private static final Long READ_CAPACITY = Long.valueOf(10);
    private static final Long WRITE_CAPACITY = Long.valueOf(5);

    private static final BridgeConfig CONFIG = BridgeConfigFactory.getConfig();

    private static final AmazonDynamoDB DYNAMO;
    static {
        String awsKey = CONFIG.getProperty("aws.key");
        String secretKey = CONFIG.getProperty("aws.secret.key");
        DYNAMO = new AmazonDynamoDBClient(new BasicAWSCredentials(awsKey, secretKey));
    }

    /**
     * Creates DynamoDB tables, if they do not exist yet, from the annotated types.
     * in the package "org.sagebionetworks.bridge.dynamodb". Throws an error
     * if the table exists but the schema (hash key, range key, and secondary indices)
     * does not match.
     */
    public static void init(String dynamoPackage) {
        beforeInit();
        List<TableDescription> tables = getAnnotatedTables(dynamoPackage);
        initTables(tables);
    }

    /**
     * For phasing out obsolete schemas.
     */
    static void beforeInit() {
        deleteTable("HealthCodeSalt");
    }

    static void deleteTable(String table) {
        table = getTableName(table);
        try {
            DescribeTableResult tableResult = DYNAMO.describeTable(table);
            TableDescription tableDscr = tableResult.getTable();
            String status = tableDscr.getTableStatus();
            if (TableStatus.DELETING.toString().equalsIgnoreCase(status)) {
                return;
            } else if (!TableStatus.ACTIVE.toString().equalsIgnoreCase(status)) {
                waitForActive(tableDscr);
            }
            logger.info("Deleting table " + table);
            DYNAMO.deleteTable(table);
            logger.info("Table " + table + " deleted.");
        } catch(ResourceNotFoundException e) {
            logger.warn("Table " + table + " does not exist.");
        }
    }

    /**
     * Prefix the table name with '{env}-' and '{user}-'.
     */
    static String getTableName(String table) {
        Environment env = CONFIG.getEnvironment();
        return env.getEnvName() + "-" + CONFIG.getUser() + "-" + table;
    }

    /**
     * Converts the annotated DynamoDBTable types to a list of TableDescription.
     */
    static List<TableDescription> getAnnotatedTables(final String dynamoPackage) {
        List<TableDescription> tables = new ArrayList<TableDescription>();
        List<Class<?>> classes = loadDynamoTableClasses(dynamoPackage);
        for (Class<?> clazz : classes) {
            final List<KeySchemaElement> keySchema = new ArrayList<KeySchemaElement>();
{'fraction_non_alphanumeric': 0.0973253330621377, 'fraction_numerical': 0.005898505034068952, 'mean_word_length': 4.208686440677966, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2559633', 'n_tokens_mistral': 2957, 'n_tokens_neox': 2896, 'n_words': 533}