diff options
Diffstat (limited to 'src/com/p4square/grow/backend/dynamo/DbTool.java')
-rw-r--r-- | src/com/p4square/grow/backend/dynamo/DbTool.java | 341 |
1 files changed, 341 insertions, 0 deletions
diff --git a/src/com/p4square/grow/backend/dynamo/DbTool.java b/src/com/p4square/grow/backend/dynamo/DbTool.java new file mode 100644 index 0000000..5784f3e --- /dev/null +++ b/src/com/p4square/grow/backend/dynamo/DbTool.java @@ -0,0 +1,341 @@ +/* + * Copyright 2014 Jesse Morgan + */ + +package com.p4square.grow.backend.dynamo; + +import java.util.Arrays; +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; + +import com.amazonaws.auth.AWSCredentials; + +import com.p4square.grow.backend.dynamo.DynamoDatabase; +import com.p4square.grow.backend.dynamo.DynamoKey; +import com.p4square.grow.config.Config; +import com.p4square.grow.model.UserRecord; +import com.p4square.grow.provider.Provider; + +/** + * + * @author Jesse Morgan <jesse@jesterpm.net> + */ +public class DbTool { + private static final FilenameFilter JSON_FILTER = new JsonFilter(); + + private static Config mConfig; + private static DynamoDatabase mDatabase; + + public static void usage() { + System.out.println("java com.p4square.grow.backend.dynamo.DbTool <command>...\n"); + System.out.println("Commands:"); + System.out.println("\t--domain <domain> Set config domain"); + System.out.println("\t--dev Set config domain to dev"); + System.out.println("\t--config <file> Merge in config file"); + System.out.println("\t--list List all tables"); + System.out.println("\t--create <table> <reads> <writes> Create a table"); + System.out.println("\t--update <table> <reads> <writes> Update table throughput"); + System.out.println("\t--drop <table> Delete a table"); + System.out.println("\t--get <table> <key> <attribute> Get a value"); + System.out.println("\t--put <table> <key> <attribute> <value> Put a value"); + System.out.println(); + System.out.println("Bootstrap Commands:"); + System.out.println("\t--bootstrap <data> Create all tables and import all data"); + System.out.println("\t--loadStrings <data> Load all videos and questions"); + System.out.println("\t--destroy Drop all tables"); + System.out.println("\t--addadmin <user> <pass> Add a backend account"); + } + + public static void main(String... args) { + if (args.length == 0) { + usage(); + System.exit(1); + } + + mConfig = new Config(); + + try { + int offset = 0; + while (offset < args.length) { + if ("--domain".equals(args[offset])) { + mConfig.setDomain(args[offset + 1]); + mDatabase = null; + offset += 2; + + } else if ("--dev".equals(args[offset])) { + mConfig.setDomain("dev"); + mDatabase = null; + offset += 1; + + } else if ("--config".equals(args[offset])) { + mConfig.updateConfig(args[offset + 1]); + mDatabase = null; + offset += 2; + + } else if ("--list".equals(args[offset])) { + //offset = list(args, ++offset); + + } else if ("--create".equals(args[offset])) { + offset = create(args, ++offset); + + } else if ("--update".equals(args[offset])) { + offset = update(args, ++offset); + + } else if ("--drop".equals(args[offset])) { + offset = drop(args, ++offset); + + } else if ("--get".equals(args[offset])) { + offset = get(args, ++offset); + + } else if ("--put".equals(args[offset])) { + offset = put(args, ++offset); + + /* Bootstrap Commands */ + } else if ("--bootstrap".equals(args[offset])) { + offset = bootstrapTables(args, ++offset); + offset = loadStrings(args, offset); + + } else if ("--loadStrings".equals(args[offset])) { + offset = loadStrings(args, ++offset); + + } else if ("--destroy".equals(args[offset])) { + offset = destroy(args, ++offset); + + } else if ("--addadmin".equals(args[offset])) { + offset = addAdmin(args, ++offset); + + } else { + throw new IllegalArgumentException("Unknown command " + args[offset]); + } + } + } catch (Exception e) { + e.printStackTrace(); + System.exit(2); + } + } + + private static DynamoDatabase getDatabase() { + if (mDatabase == null) { + AWSCredentials creds = new AWSCredentials() { + @Override + public String getAWSAccessKeyId() { + return mConfig.getString("awsAccessKey"); + } + @Override + public String getAWSSecretKey() { + return mConfig.getString("awsSecretKey"); + } + }; + + String endpoint = mConfig.getString("dynamoEndpoint"); + if (endpoint != null) { + mDatabase = new DynamoDatabase(creds, endpoint); + } else { + mDatabase = new DynamoDatabase(creds); + } + } + + return mDatabase; + } + + private static int create(String[] args, int offset) { + String name = args[offset++]; + long reads = Long.parseLong(args[offset++]); + long writes = Long.parseLong(args[offset++]); + + DynamoDatabase db = getDatabase(); + + db.createTable(name, reads, writes); + + return offset; + } + + private static int update(String[] args, int offset) { + String name = args[offset++]; + long reads = Long.parseLong(args[offset++]); + long writes = Long.parseLong(args[offset++]); + + DynamoDatabase db = getDatabase(); + + db.updateTable(name, reads, writes); + + return offset; + } + + private static int drop(String[] args, int offset) { + String name = args[offset++]; + + DynamoDatabase db = getDatabase(); + + db.deleteTable(name); + + return offset; + } + + private static int get(String[] args, int offset) { + String table = args[offset++]; + String key = args[offset++]; + String attribute = args[offset++]; + + DynamoDatabase db = getDatabase(); + + String value = db.getAttribute(DynamoKey.newAttributeKey(table, key, attribute)); + + if (value == null) { + value = "<null>"; + } + + System.out.printf("%s %s:%s\n%s\n\n", table, key, attribute, value); + + return offset; + } + + private static int put(String[] args, int offset) { + String table = args[offset++]; + String key = args[offset++]; + String attribute = args[offset++]; + String value = args[offset++]; + + DynamoDatabase db = getDatabase(); + + db.putAttribute(DynamoKey.newAttributeKey(table, key, attribute), value); + + return offset; + } + + private static int bootstrapTables(String[] args, int offset) { + DynamoDatabase db = getDatabase(); + + db.createTable("strings", 10, 1); + db.createTable("accounts", 10, 1); + db.createTable("assessments", 10, 5); + db.createTable("training", 10, 5); + db.createTable("feedthreads", 10, 1); + db.createTable("feedmessages", 10, 1); + + return offset; + } + + private static int loadStrings(String[] args, int offset) throws IOException { + String data = args[offset++]; + File baseDir = new File(data); + + DynamoDatabase db = getDatabase(); + + insertQuestions(baseDir); + insertVideos(baseDir); + insertDefaultPlaylist(baseDir); + + return offset; + } + + private static int destroy(String[] args, int offset) { + DynamoDatabase db = getDatabase(); + + final String[] tables = { "strings", + "accounts", + "assessments", + "training", + "feedthreads", + "feedmessages" + }; + + for (String table : tables) { + try { + db.deleteTable(table); + } catch (Exception e) { + System.err.println("Deleting " + table + ": " + e.getMessage()); + } + } + + return offset; + } + + private static int addAdmin(String[] args, int offset) throws IOException { + String user = args[offset++]; + String pass = args[offset++]; + + DynamoDatabase db = getDatabase(); + + UserRecord record = new UserRecord(); + record.setId(user); + record.setBackendPassword(pass); + + Provider<DynamoKey, UserRecord> provider = new DynamoProviderImpl(db, UserRecord.class); + provider.put(DynamoKey.newAttributeKey("accounts", user, "value"), record); + + return offset; + } + + private static void insertQuestions(File baseDir) throws IOException { + DynamoDatabase db = getDatabase(); + File questions = new File(baseDir, "questions"); + + File[] files = questions.listFiles(JSON_FILTER); + Arrays.sort(files); + + for (File file : files) { + String filename = file.getName(); + String questionId = filename.substring(0, filename.lastIndexOf('.')); + + byte[] encoded = Files.readAllBytes(file.toPath()); + String value = new String(encoded, StandardCharsets.UTF_8); + db.putAttribute(DynamoKey.newAttributeKey("strings", + "/questions/" + questionId, "value"), value); + System.out.println("Inserted /questions/" + questionId); + } + + String filename = files[0].getName(); + String first = filename.substring(0, filename.lastIndexOf('.')); + int count = files.length; + String summary = "{\"first\": \"" + first + "\", \"count\": " + count + "}"; + db.putAttribute(DynamoKey.newAttributeKey("strings", "/questions", "value"), summary); + System.out.println("Inserted /questions"); + } + + private static void insertVideos(File baseDir) throws IOException { + DynamoDatabase db = getDatabase(); + File videos = new File(baseDir, "videos"); + + for (File topic : videos.listFiles()) { + if (!topic.isDirectory()) { + continue; + } + + String topicName = topic.getName(); + + File[] files = topic.listFiles(JSON_FILTER); + for (File file : files) { + String filename = file.getName(); + String videoId = filename.substring(0, filename.lastIndexOf('.')); + + byte[] encoded = Files.readAllBytes(file.toPath()); + String value = new String(encoded, StandardCharsets.UTF_8); + db.putAttribute(DynamoKey.newAttributeKey("strings", + "/training/" + topicName, videoId), value); + System.out.println("Inserted /training/" + topicName + ":" + videoId); + } + } + } + + private static void insertDefaultPlaylist(File baseDir) throws IOException { + DynamoDatabase db = getDatabase(); + File file = new File(baseDir, "videos/playlist.json"); + + byte[] encoded = Files.readAllBytes(file.toPath()); + String value = new String(encoded, StandardCharsets.UTF_8); + db.putAttribute(DynamoKey.newAttributeKey("strings", + "/training/defaultplaylist", "value"), value); + System.out.println("Inserted /training/defaultplaylist"); + } + + private static class JsonFilter implements FilenameFilter { + @Override + public boolean accept(File dir, String name) { + return name.endsWith(".json"); + } + } +} |