/*
 * Copyright (c) 2016. Taimos GmbH http://www.taimos.de
 */

package de.taimos.dvalin.dynamodb;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
import com.amazonaws.services.dynamodbv2.model.CreateTableResult;
import com.amazonaws.services.dynamodbv2.model.DescribeTableResult;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodbv2.model.ResourceNotFoundException;

import de.taimos.dvalin.cloud.aws.AWSClient;

public abstract class AbstractDynamoDAO<T> {

    public final Logger LOGGER = LoggerFactory.getLogger(this.getClass());

    @AWSClient
    protected AmazonDynamoDBClient client;

    protected DynamoDBMapper mapper;

    @Value("${dynamodb.url:}")
    private String dynamodbUrl;

    @PostConstruct
    public final void init() {
        if (!this.dynamodbUrl.isEmpty()) {
            this.client.setEndpoint(this.dynamodbUrl);
        }
        this.mapper = new DynamoDBMapper(this.client);
        try {
            DescribeTableResult tableResult = this.client.describeTable(this.getTableName());
            LOGGER.info("DynamoDB table exists: {}", tableResult.getTable());
        } catch (ResourceNotFoundException e) {
            CreateTableRequest request = this.mapper.generateCreateTableRequest(this.getEntityClass());
            LOGGER.info("Create DynamoDB table: {}", request);
            request.setProvisionedThroughput(getProvisionedThroughput());
            this.modifyCreateTableRequest(request);
            CreateTableResult table = this.client.createTable(request);
            LOGGER.info("Created table: {}", table.getTableDescription());
        }
    }

    /**
     * override to adjust crea table requests
     *
     * @param request the request to modify
     */
    protected void modifyCreateTableRequest(CreateTableRequest request) {
        //
    }

    /**
     * the provisioned throughput of newly created tables. Defaults to (1,1)
     *
     * @return provisioned throughput
     */
    protected ProvisionedThroughput getProvisionedThroughput() {
        return new ProvisionedThroughput(1L, 1L);
    }

    /**
     * the class of the base object to use for this DAO
     *
     * @return entity class
     */
    protected abstract Class<T> getEntityClass();

    /**
     * override to use custom table name instead of @{@link DynamoDBTable} annotation
     *
     * @return the name of the table to use
     */
    protected String getTableName() {
        Class<T> entityClass = getEntityClass();
        if (!entityClass.isAnnotationPresent(DynamoDBTable.class)) {
            throw new IllegalStateException("Used getTableName on entity without @DynamoDBTable annotation");
        }
        return entityClass.getAnnotation(DynamoDBTable.class).tableName();
    }

}

@@ -193,67 +193,8 @@
 ory;
-%0Aimport org.springframework.beans.factory.annotation.Value;
 %0A%0Aim
@@ -921,16 +921,47 @@
 WSClient
+(endpoint = %22$%7Bdynamodb.url:%7D%22)
 %0A    pro
@@ -1044,224 +1044,52 @@
    @
-Value(%22$%7Bdynamodb.url:%7D%22)%0A    private String dynamodbUrl;%0A%0A    @PostConstruct%0A    public final void init() %7B%0A        if (!this.dynamodbUrl.isEmpty()) %7B%0A            this.client.setEndpoint(this.dynamodbUrl);%0A        %7D
+PostConstruct%0A    public final void init() %7B
 %0A   

use endpoint attribute in DynamoDB DAO