Usar extensões - AWS SDK for Java 2.x

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Usar extensões

A API do Cliente Aprimorado do DynamoDB fornece suporte a extensões de complemento que fornecem funcionalidades além das operações de mapeamento. As extensões têm dois métodos de hook, beforeWrite() e afterRead(). beforeWrite() modifica uma operação de gravação antes que ela aconteça, e o método afterRead() modifica os resultados de uma operação de leitura depois que ela acontece. Uma vez que algumas operações (como atualizações de itens) realizam uma gravação e depois uma leitura, os dois métodos de hook são chamados.

As extensões são carregadas na ordem em que são especificadas no construtor do cliente aprimorado. A ordem de carregamento pode ser importante porque uma extensão pode atuar em valores que foram transformados por uma extensão anterior.

A API de cliente aprimorado vem com um conjunto de extensões de complemento localizadas no pacote de extensions. Por padrão, o cliente aprimorado carrega a VersionedRecordExtension e a AtomicCounterExtension. Você pode substituir o comportamento padrão com o construtor de cliente avançado e carregar qualquer extensão. Você também pode especificar nenhuma se não quiser as extensões padrão.

Se você carregar suas próprias extensões, o cliente aprimorado não carregará nenhuma extensão padrão. Se você quiser o comportamento fornecido por uma extensão padrão, precisará adicioná-la explicitamente à lista de extensões.

No exemplo a seguir, uma extensão personalizada chamada verifyChecksumExtension é carregada após a VersionedRecordExtension, que geralmente é carregada por padrão. A AtomicCounterExtension não está carregada neste exemplo.

DynamoDbEnhancedClientExtension versionedRecordExtension = VersionedRecordExtension.builder().build(); DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder() .dynamoDbClient(dynamoDbClient) .extensions(versionedRecordExtension, verifyChecksumExtension) .build();

VersionedRecordExtension

A VersionedRecordExtension é carregada por padrão e incrementará e rastreará o número da versão do item à medida que os itens forem gravados no banco de dados. Uma condição será adicionada a cada gravação que faz com que a gravação falhe se o número da versão do item real persistido não corresponder ao valor que o aplicativo leu pela última vez. Esse comportamento fornece efetivamente um bloqueio positivo para atualizações de itens. Se outro processo atualizar um item entre o momento em que o primeiro processo leu o item e está gravando uma atualização nele, a gravação falhará.

Para especificar qual atributo usar para rastrear o número da versão do item, marque um atributo numérico no esquema da tabela.

O trecho a seguir especifica que o atributo version deve conter o número da versão do item.

@DynamoDbVersionAttribute public Integer getVersion() {...}; public void setVersion(Integer version) {...};

A abordagem equivalente do esquema de tabela estática é mostrada no trecho a seguir.

.addAttribute(Integer.class, a -> a.name("version") .getter(Customer::getVersion) .setter(Customer::setVersion) // Apply the 'version' tag to the attribute. .tags(VersionedRecordExtension.AttributeTags.versionAttribute())

AtomicCounterExtension

A AtomicCounterExtension é carregada por padrão e incrementa um atributo numérico marcado sempre que um registro é gravado no banco de dados. Os valores iniciais e de incremento podem ser especificados. Se nenhum valor for especificado, o valor inicial será definido como 0 e o valor do atributo será incrementado em 1.

Para especificar qual atributo é um contador, marque um atributo do tipo Long no esquema da tabela.

O trecho a seguir mostra o uso dos valores padrão de início e de incremento para o atributo counter.

@DynamoDbAtomicCounter public Long getCounter() {...}; public void setCounter(Long counter) {...};

A abordagem do esquema de tabela estática é mostrada no trecho a seguir. A extensão do contador atômico usa um valor inicial de 10 e incrementa o valor em 5 cada vez que o registro é gravado.

.addAttribute(Integer.class, a -> a.name("counter") .getter(Customer::getCounter) .setter(Customer::setCounter) // Apply the 'atomicCounter' tag to the attribute with start and increment values. .tags(StaticAttributeTags.atomicCounter(10L, 5L))

AutoGeneratedTimestampRecordExtension

A AutoGeneratedTimestampRecordExtension atualiza automaticamente os atributos marcados do tipo Instant com um carimbo de data/hora atual sempre que o item é gravado com sucesso no banco de dados.

Essa extensão não é carregada por padrão. Portanto, você precisa especificá-la como uma extensão personalizada ao criar o cliente aprimorado, conforme mostrado no primeiro exemplo deste tópico.

Para especificar qual atributo atualizar com o carimbo de data/hora atual, marque o atributo Instant no esquema da tabela.

O atributo lastUpdate é o alvo do comportamento das extensões no trecho a seguir. Observe a exigência de que o atributo seja um tipo Instant.

@DynamoDbAutoGeneratedTimestampAttribute public Instant getLastUpdate() {...} public void setLastUpdate(Instant lastUpdate) {...}

A abordagem equivalente do esquema de tabela estática é mostrada no trecho a seguir.

.addAttribute(Instant.class, a -> a.name("lastUpdate") .getter(Customer::getLastUpdate) .setter(Customer::setLastUpdate) // Applying the 'autoGeneratedTimestamp' tag to the attribute. .tags(AutoGeneratedTimestampRecordExtension.AttributeTags.autoGeneratedTimestampAttribute())

Extensões personalizadas

A classe de extensão personalizada a seguir mostra um método beforeWrite() que usa uma expressão de atualização. Após a linha de comentário 2, criamos um SetAction para definir o atributo registrationDate se o item no banco de dados ainda não tiver um atributo registrationDate. Sempre que um objeto Customer é atualizado, a extensão garante que um registrationDate esteja definido.

public final class CustomExtension implements DynamoDbEnhancedClientExtension { // 1. In a custom extension, use an UpdateExpression to define what action to take before // an item is updated. @Override public WriteModification beforeWrite(DynamoDbExtensionContext.BeforeWrite context) { if ( context.operationContext().tableName().equals("Customer") && context.operationName().equals(OperationName.UPDATE_ITEM)) { return WriteModification.builder() .updateExpression(createUpdateExpression()) .build(); } return WriteModification.builder().build(); // Return an "empty" WriteModification instance if the extension should not be applied. // In this case, if the code is not updating an item on the Customer table. } private static UpdateExpression createUpdateExpression() { // 2. Use a SetAction, a subclass of UpdateAction, to provide the values in the update. SetAction setAction = SetAction.builder() .path("registrationDate") .value("if_not_exists(registrationDate, :regValue)") .putExpressionValue(":regValue", AttributeValue.fromS(Instant.now().toString())) .build(); // 3. Build the UpdateExpression with one or more UpdateAction. return UpdateExpression.builder() .addAction(setAction) .build(); } }