I am testing DynamoDB tables and want to set up different table names for prod and dev environment using the prefix "dev_" for development.
I made this test to print the table name:
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig.TableNameOverride;
TableNameOverride tbl = new TableNameOverride("test").withTableNamePrefix("dev_");
System.out.println("name=" + tbl.getTableName() + " prefix=" + tbl.getTableNamePrefix());
This prints: name=null prefix=dev_
How come the name here is null ?
TableNameOverride tbl = new TableNameOverride("test");//.withTableNamePrefix("dev_");
System.out.println("name=" + tbl.getTableName() + " prefix=" + tbl.getTableNamePrefix());
This prints: name=test prefix=null
*How can I get the table name to be "dev_test" ?*
I want to use this later to get a "dev_" prefix for all tables in development mode like this:
DynamoDBTable annotation = (DynamoDBTable) myclass.getClass().getAnnotation(DynamoDBTable.class);
TableNameOverride tbl = new TableNameOverride(annotation.tableName()).withTableNamePrefix("dev_");
Or is there another solution to separate between dev and prod tables?
I first thought of putting them in separate regions but not sure about this.
Could also use this:
mapper.save(ck, new DynamoDBMapperConfig(new TableNameOverride((isDev ? "dev_" : "") + annotation.tableName())));
TableNameOverride object—Instructs the mapper instance to ignore the table name specified by a class's DynamoDBTable annotation, and instead use a different table name that you supply. This is useful when partitioning your data into multiple tables at runtime.
Binary − They store any binary data, e.g., encrypted data, images, and compressed text. DynamoDB views its bytes as unsigned. Boolean − They store true or false. Null − They represent an unknown or undefined state.
The DynamoDBMapper class is the entry point to Amazon DynamoDB. It provides access to a DynamoDB endpoint and enables you to access your data in various tables. It also enables you to perform various create, read, update, and delete (CRUD) operations on items, and run queries and scans against tables.
DynamoDB supports the following data types: Scalar – Number, String, Binary, Boolean, and Null. Multi-valued – String Set, Number Set, and Binary Set.
I've faced the same situation and struggled with myself a couple of days to get that working.
Just in case you're using DynamoDB + Spring here is what worked for me:
POJO class:
@DynamoDBTable(tableName = "APP-ACCESSKEY")
public class AccessKey {
@NotBlank
@Size(min = 1, max = 36)
private String accessToken;
@NotNull
@Size(min = 3, max = 15)
private String userName;
private Date dateInsertion;
public AccessKey() {
// ... All POJO stuff
}
Spring configuration:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<!-- Amazon Credentials -->
<bean id="tableNameOverride" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod" value="com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig.TableNameOverride.withTableNamePrefix"/>
<property name="arguments" value="DES-" />
</bean>
<bean id="dynamoDBMapperConfig" class="com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig">
<constructor-arg index="0" ref="tableNameOverride" />
</bean>
<bean id="BasicAWSCredentials" class="com.amazonaws.auth.BasicAWSCredentials">
<constructor-arg index="0" value="${amazon.accessKey}" />
<constructor-arg index="1" value="${amazon.secretKey}" />
</bean>
<bean id="amazonDynamoDBClient" class="com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient">
<constructor-arg index="0" ref="BasicAWSCredentials" />
<property name="endpoint" value="http://dynamodb.us-west-2.amazonaws.com" />
</bean>
<bean id="dynamoDBMapper" class="com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper">
<constructor-arg index="0" ref="amazonDynamoDBClient" />
<constructor-arg index="1" ref="dynamoDBMapperConfig" />
</bean>
</beans>
Explanation:
Taking into account that my AccessKey object point to APP-ACCESSKEY table on AWS DynamodDB then it turns out that after running this, your application will start to point to DES-APP-ACCESSKEY.
Hope it helps someone who's facing a situation akin to it
Cheers
Same as Paolo Almeidas solution, but with Spring-Boot annotations. Just wanted to share it and maybe save someone time:
I have dynamodb tables for each namespace, e.g. myApp-dev-UserTable, myApp-prod-UserTable and I am using the EKS_NAMESPACE env variable, which in my case gets injected into the pods by kubernetes.
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig;
@Configuration
@EnableDynamoDBRepositories(basePackages = "de.dynamodb")
public class DynamoDBConfig {
@Value("${EKS_NAMESPACE}")
String eksNamespace;
@Bean
public AmazonDynamoDB amazonDynamoDB() {
return AmazonDynamoDBClientBuilder.standard()
.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(
"dynamodb.eu-central-1.amazonaws.com", "eu-central-1"))
.withCredentials(awsCredentials())
.build();
}
@Bean
public AWSCredentialsProvider awsCredentials() {
return WebIdentityTokenCredentialsProvider.builder().build();
}
// Table Name override:
@Bean
public DynamoDBMapperConfig.TableNameOverride tableNameOverride() {
return DynamoDBMapperConfig.TableNameOverride.withTableNamePrefix("myApp-" + eksNamespace + "-");
}
@Bean
public DynamoDBMapperConfig dynamoDBMapperConfig() {
return DynamoDBMapperConfig.builder().withTableNameOverride(tableNameOverride()).build();
}
@Bean
// Marked as primary bean to override default bean.
@Primary
public DynamoDBMapper dynamoDBMapper() {
return new DynamoDBMapper(amazonDynamoDB(), dynamoDBMapperConfig());
}
}
With a table like this:
@Data
@DynamoDBTable(tableName = "UserTable")
public class User {
@DynamoDBHashKey
private String userId;
@DynamoDBAttribute
private String foo;
@DynamoDBAttribute
private String bar;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With