/*** * Scan classes to determine which tables and indexes need to be created * * TODO - DynamoDB has a limit of how many tables can be created at once, I think 10 as of now. * This method does not batch but really needs to, so it only tries to create up 10 tables at the same time * * @param packagePrefix * @param blockUntilActive - If true this method will not return until the table is active or maxBlockTimeSeconds has expired * @param maxBlockTimeSeconds - The maximum amount of time to block for each table until the table becomes active */ public void scan(final String packagePrefix, boolean blockUntilActive, long maxBlockTimeSeconds){ final List<String> createdTables = Lists.newArrayList(); final Reflections reflections = new Reflections(packagePrefix); final Set<Class<?>> tableClasses = reflections.getTypesAnnotatedWith(DynamoDBTable.class); for(Class<?> clazz : tableClasses){ if(!tableExists(clazz)){ final CreateTableResult result = this.createTable(clazz); if(result!=null && result.getTableDescription()!=null){ final TableDescription description = result.getTableDescription(); /** If the table is not active add it to the list of tables to wait on **/ if(!ACTIVE_TABLE_STATUS.equalsIgnoreCase(description.getTableStatus())){ createdTables.add(description.getTableName()); } } } } /** If specified, wait for all the tables to become if active **/ if(blockUntilActive){ for(final String table : createdTables){ this.waitForTableToBecomeActive(table, maxBlockTimeSeconds, DEFAULT_PAUSE_TIME_SECONDS); } } }
/*** * Create the table and the associated indexes if it does not already exist * @param reflections * @param clazz */ private CreateTableResult createTable(Class<?> clazz) { final String tableName = this.getClassAnnotationValue(clazz, DynamoDBTable.class, String.class, "tableName"); final Method hashKeyMember = this.getMethodForAnnotation(clazz, DynamoDBHashKey.class); final DynamoDBHashKey hashKeyAnno = hashKeyMember.getAnnotation(DynamoDBHashKey.class); final String hashKeyName = this.getAnnotationValue(hashKeyAnno, "attributeName", String.class); String rangeKeyName = null; final Method rangeKeyMember = this.getMethodForAnnotation(clazz, DynamoDBRangeKey.class); if(rangeKeyMember!=null){ DynamoDBRangeKey rangeKeyAnno = rangeKeyMember.getAnnotation(DynamoDBRangeKey.class); rangeKeyName = this.getAnnotationValue(rangeKeyAnno, "attributeName", String.class); } final Set<Method> hashKeyIndexFields = this.getMethodsAnnotatedWith(DynamoDBIndexHashKey.class, clazz); final Set<Method> rangeKeyIndexFields = this.getMethodsAnnotatedWith(DynamoDBIndexRangeKey.class, clazz); final Map<String, GlobalIndex> globalIndexes = this.createGlobalIndexes(hashKeyIndexFields, rangeKeyIndexFields, clazz); final Map<String, RangeKeyIndexField> localIndexes = this.createLocalIndexMap(rangeKeyIndexFields); final CreateTableRequest tableRequest = this.createCreateTableRequest(tableName, hashKeyName, rangeKeyName, globalIndexes, localIndexes); final CreateTableResult result = this.client.createTable(tableRequest); return result; }
@Override protected boolean shouldCreatePersistentEntityFor(TypeInformation<?> type) { boolean hasHashKey = false; boolean hasRangeKey = false; for (Method method : type.getType().getMethods()) { if (method.isAnnotationPresent(DynamoDBHashKey.class)) hasHashKey = true; if (method.isAnnotationPresent(DynamoDBRangeKey.class)) hasRangeKey = true; } for (Field field : type.getType().getFields()) { if (field.isAnnotationPresent(DynamoDBHashKey.class)) hasHashKey = true; if (field.isAnnotationPresent(DynamoDBRangeKey.class)) hasRangeKey = true; } return type.getType().isAnnotationPresent(DynamoDBTable.class) || (hasHashKey && hasRangeKey); }
@Override protected Configuration createConfiguration(RoundEnvironment roundEnv) { Class<? extends Annotation> entities = QueryEntities.class; Class<? extends Annotation> entity = DynamoDBTable.class; Class<? extends Annotation> skip = DynamoDBIgnore.class; DefaultConfiguration conf = new DefaultConfiguration(roundEnv, processingEnv.getOptions(), Collections.<String>emptySet(), entities, entity, null, null, null, skip); return conf; }
/*** * * @param clazz * @return tableStatus * @throws ResourceNotFoundException */ public String getTableStatus(Class<?> clazz) throws ResourceNotFoundException{ final String tableName = this.getClassAnnotationValue(clazz, DynamoDBTable.class, String.class, "tableName"); if(!Strings.isNullOrEmpty(tableName)){ this.getTableStatus(tableName); } return null; }
protected String getDomainName() { return getPrefix() + getType().getAnnotation(DynamoDBTable.class).tableName(); }
private String extractTableName(Class<? extends IDomain> domain){ return domain.getAnnotation(DynamoDBTable.class).tableName(); }