DEV Community

Hernani Almeida
Hernani Almeida

Posted on

Desacoplando a camada de domínio de uma aplicação das outras camadas - parte 2

Ferramentas necessárias:

Vamos agora fazer a transição da nossa aplicação do banco de dados Postgres para DynamoDb, para isso precisamos adicionar as dependências referente ao DynamoDb e retirar as dependências referente ao Postgres em nosso arquivo pom.xml que devera ficar assim.
pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>ddd</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>ddd</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.amazonaws</groupId>
                <artifactId>aws-java-sdk-bom</artifactId>
                <version>1.11.614</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.github.derjust</groupId>
            <artifactId>spring-data-dynamodb</artifactId>
            <version>5.1.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>
Enter fullscreen mode Exit fullscreen mode

Vamos modificar também nosso arquivo application.properties para deixar apenas o endpoint de acesso ao nosso banco de dados DynamoDb.
application.properties

server.error.include-message=always
aws.amazonDynamoDBEndpoint=http://localhost:8000
Enter fullscreen mode Exit fullscreen mode

Rode o seguinte comando em seu terminal CMD para criar um banco de dados AWS/DynamoDb dentro de um container docker.

docker run -p 8000:8000 amazon/dynamodb-local -jar DynamoDBLocal.jar -inMemory -sharedDb

Vamos agora fazer a transição do armazenamento da nossa aplicação de Postgres para DynamoDb, para isso só precisaremos alterar nossa classe UsuarioAbstractRepositoryDB,mapear nossa tabela dynamoDb na classe Usuario e criar uma classe de configuração de acesso ao Aws/DynamoDb.
Dentro do package infrastructure crie um pakage config e dentro dele um package dynamodb, dentro do package dynamodb crie a classe de configuração DynamoDbConfig.
DynamoDbConfig

import com.amazonaws.client.builder.AwsClientBuilder;
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;
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodbv2.util.TableUtils;
import com.example.ddd.core.usuario.Usuario;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DynamoDbConfig {

    @Value(("${aws.amazonDynamoDBEndpoint}"))
    private String amazonDynamoDBEndpoint;

    @Bean
    public DynamoDBMapper dynamoDBMapper() {
        AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
                .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(amazonDynamoDBEndpoint, "us-west-2"))
                .build();
        DynamoDBMapperConfig mapperConfig = DynamoDBMapperConfig.builder()
                .withSaveBehavior(DynamoDBMapperConfig.SaveBehavior.CLOBBER)
                .withConsistentReads(DynamoDBMapperConfig.ConsistentReads.CONSISTENT)
                .withTableNameOverride(null)
                .withPaginationLoadingStrategy(DynamoDBMapperConfig.PaginationLoadingStrategy.EAGER_LOADING)
                .build();
        DynamoDBMapper dynamoDBMapper = new DynamoDBMapper(client, mapperConfig);
        init(dynamoDBMapper, client);
        return dynamoDBMapper;
    }


    public void init(DynamoDBMapper dynamoDBMapper, AmazonDynamoDB client) {

        CreateTableRequest tableRequest = dynamoDBMapper.generateCreateTableRequest(Usuario.class);
        tableRequest.setProvisionedThroughput(new ProvisionedThroughput(1L, 1L));

        if (TableUtils.createTableIfNotExists(client, tableRequest)) {
            System.out.println("Table created");
        }

    }

}
Enter fullscreen mode Exit fullscreen mode

Altere a classe UsuarioAbstractRepositoryDB para métodos que irão acessar o dynamoDb e armazenar ou retornar os dados que precisamos.
UsuarioAbstractRepositoryDB

import java.util.List;

@Repository
public class UsuarioAbstractRepositoryDB {

    private DynamoDBMapper dynamoDBMapper;


    @Autowired
    public UsuarioAbstractRepositoryDB(DynamoDBMapper dynamoDBMapper) {
        this.dynamoDBMapper = dynamoDBMapper;
    }

    public Usuario buscaUsuarioPorId(String usuarioId) {
        return dynamoDBMapper.load(Usuario.class, usuarioId);
    }

   public List<Usuario> buscaUsuarios() {

       final DynamoDBScanExpression paginatedScanListExpression = new DynamoDBScanExpression();
       final PaginatedScanList<Usuario> usuarioList = dynamoDBMapper.scan(Usuario.class, paginatedScanListExpression);
       return usuarioList;
   }

    public String deletaUsuario(String usuarioId){
        Usuario usuario = dynamoDBMapper.load(Usuario.class,usuarioId);
        dynamoDBMapper.delete(usuario);
        return "Usuario deletado com sucesso";
    }

    public Usuario criaUsuario(Usuario usuario) {
        dynamoDBMapper.save(usuario);
        return usuario;
    }

    public Usuario updateUsuario(String usuarioId, Usuario usuario) {

        dynamoDBMapper.save(usuario,
                new DynamoDBSaveExpression()
                        .withExpectedEntry("usuarioId",
                                new ExpectedAttributeValue(
                                        new AttributeValue().withS(usuarioId)
                                )));
        Usuario usuarioAtualizado = buscaUsuarioPorId(usuarioId);
        return usuarioAtualizado;
    }
}
Enter fullscreen mode Exit fullscreen mode

Agora so precisamos mapear a criação da nossa entidade usuario dentro do banco de dados dynamoDb, para isso altere a classe Usuario da seguinte forma.
Usuario

import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAutoGeneratedKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;

@DynamoDBTable(tableName = "usuario")
public class Usuario {

    @DynamoDBHashKey(attributeName = "usuarioId")
    @DynamoDBAutoGeneratedKey
    private String userId;

    @DynamoDBAttribute(attributeName = "name")
    private String name;

    @DynamoDBAttribute(attributeName = "email")
    private String email;

    @DynamoDBAttribute(attributeName = "cpf")
    private String cpf;

    @Deprecated
    public Usuario() {
    }

    public Usuario(String name, String email, String cpf) {
        this.name = name;
        this.email = email;
        this.cpf = cpf;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getName() {
        return name;
    }

    public String getEmail() {
        return email;
    }

    public String getCpf() {
        return cpf;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public void setCpf(String cpf) {
        this.cpf = cpf;
    }

}
Enter fullscreen mode Exit fullscreen mode

E pronto, transição realizada sem precisar mexer na camada de domínio ou na camada de acesso externo de nossa aplicação, podemos rodar nossa aplicação e testar via Postman.

Usuario criado

Image description

Lista Usuario

Image description

Usuario Armazenado DynamoDB

Image description

E isso ai galera, essa ultima parte deixarei no meu github para quem quiser acessar
Deixo aqui também meu linkedin para quem quiser me adicionar, grato a todos que leram este artigo e bora aprender galera.

Discussion (0)