Проблема: у нас есть несколько таблиц lambdas и dynamicodb, которые мы используем в рабочей среде, при выпуске новой версии нашего кода мы иногда удаляем атрибут или добавляем атрибуты в наши классы таблиц (код Java с использованием com.amazonaws.services.dynamodbv2 .datamodeling) API высокого уровня. Когда мы внедряем новую версию кода и запрашиваем таблицу, если новый атрибут не существует для существующего элемента или мы удаляем атрибут из кода. Это нарушает код, потому что наш объект Item не соответствует производственным данным.
Мы хотели бы избежать обработки данных в prod, добавляя дополнительные атрибуты со значением по умолчанию или удаляя атрибуты для существующих элементов. Прежде чем мы развернем новую версию по ряду причин, касающихся условий гонки и ее согласованности. Что было бы предпочтительнее, если бы мы обрабатывали его на уровне кода, если атрибут не существует, автоматически добавьте его со значением по умолчанию. Или же код игнорирует атрибуты, которые не определены в классе item / table. Возможно ли это с помощью высокоуровневого Java SDK API?
Другим решением, которое мы придумали, было создание службы, которая питается дельтой (изменение между объектом элемента кода и данными в prod), которая выполняется предтрафик-лямбда, которая обрабатывает данные при развертывании новой версии лямбда Однако мы бы хотели этого избежать.
package com.ourcompany.module.dynamodb.items;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBVersionAttribute;
import lombok.Data;
@Data
@DynamoDBTable(tableName = "Boxes")
public class BoxItem {
@DynamoDBHashKey(attributeName = "boxID")
private String channelID;
#This is the field we added, the previous version did not have this field, in prod we have many items without this attribute
@DynamoDBAttribute(attributeName = "lastTimeAccess")
private String lastTimeAccess;
@DynamoDBAttribute(attributeName = "initTime")
private String initTime;
@DynamoDBAttribute(attributeName = "boxIDhash")
private String streamBoxIDHash;
@DynamoDBAttribute(attributeName = "CFD")
private String cfd;
@DynamoDBAttribute(attributeName = "originDomain")
private String originDomain;
@DynamoDBAttribute(attributeName = "lIP")
private String lIP;
@DynamoDBAttribute(attributeName = "pDomain")
private String pDomain;
Выше был изменен наш элемент с добавленным атрибутом.
package com.ourcompany.shared.module.repository.dynamob;
import ...
public class DynamoDbRepository<Item, Key> {
private final DynamoDBMapper mapper;
private static final Logger logger = LogManager.getLogger(DynamoDbRepository.class);
@Inject
public DynamoDbRepository() {
val client = AmazonDynamoDBClientBuilder
.standard()
.withRegion(Regions.US_EAST_1) // TODO: hardcoded now
.withRequestHandlers(new TracingHandler(AWSXRay.getGlobalRecorder()))
.build();
DynamoDBMapperConfig dynamoDBMapperConfig = new DynamoDBMapperConfig.Builder()
.withSaveBehavior(DynamoDBMapperConfig.SaveBehavior.UPDATE_SKIP_NULL_ATTRIBUTES)
.withTableNameResolver(new DynamoDBTableNameResolver())
.build();
mapper = new DynamoDBMapper(client, dynamoDBMapperConfig);
}
/*
* Many accessor methods are listed here below is the one where we have issue,
*/
public List<Item> findBy(Map<String, Condition> filter, final Class<Item> clazz) throws Exception {
try {
logger.trace("DynamoDbRepository findBy(filter, class)");
val scanExpression = new DynamoDBScanExpression().withScanFilter(filter).withConsistentRead(true);
PaginatedScanList<Item> ls = mapper.scan(clazz, scanExpression);
ls.loadAllResults();
return ls;
} catch (Exception ex) {
logger.trace(ex.getMessage());
throw handleException(ex);
}
}
Выше представлен наш класс картографа Dynamob DB, но только с указанным методом. Мы смогли проследить, войдя в систему до строки logger.trace («DynamoDbRepository findBy (filter, class)»); и мы знаем, что проблема возникает в маппере. Однако это не приводит к появлению исключения, поэтому мы не можем увидеть фактическую ошибку. Нам пришлось решить эту проблему, удалив все данные из таблиц в prod, после чего новая версия кода повторно заполнила записи атрибутом, и код сработал.