• leandro pereira

Mensageria com Google Cloud Pub/Sub

A comunicação assíncrona via mensagens é um dos modelos mais utilizados atualmente entre microsserviços. Vamos fazer um exemplo bem simples usando a plataforma do Google.

Vou começar mostrando o código e depois algumas configurações que precisaremos fazer. OK?

Vamos lá!!!

Para começar, vamos adicionar as seguintes dependências no projeto:

(Caso tenha dúvidas em como iniciar um projeto spring boot, veja nesse post)


<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>                                                                   
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-gcp-starter</artifactId>
            <version>1.1.1.RELEASE</version>
        </dependency>         
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-gcp-starter-pubsub</artifactId>
            <version>1.1.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
 

Agora, vamos para o código de fato:

Primeiramente vamos criar um VO que vamos usar para representar o nosso evento.


public class EventVO {
 
 private String name;
 private String email;
 
   [...] Getters/Setters and Constructor
}


Agora , vamos disponibilizar um endpoint para facilitar a publicação da mensagem.



import com.coffee.tipsgcp.vo.EventVO;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gcp.pubsub.core.publisher.PubSubPublisherTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/producer-event")
public class ProducerEventController {

 @Autowired
 PubSubPublisherTemplate pubsubPublisher;

 @Autowired
 ObjectMapper objectMapper;

 @PostMapping()
 public void sendEvent(@RequestBody EventVO event) throws JsonProcessingException {
 pubsubPublisher.publish("topico-test", objectMapper.writeValueAsString(event));
 System.out.println("Mensagem enviada para o tópico !!!");
 }
}


No exemplo acima, nós injetamos a classe PubSubPublisherTemplate que é responsável por publicar a mensagem com o método publish(). Nele informamos o nome do tópico e transformamos o nosso objeto EventVO em json para ser enviado.


E finalizando a parte do código, vamos criar um método para consumir as mensagens que publicamos. Lembrando que como estamos falando de microsserviços, o produtor e consumidor ficam em aplicações diferentes, aqui vamos colocar na mesma aplicação para facilitar o exemplo.



import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.cloud.gcp.pubsub.core.PubSubTemplate;
import org.springframework.stereotype.Component;

@Component
public class TopicSubscriber implements ApplicationRunner {

 @Autowired
 PubSubTemplate pubSubTemplate;

 @Override
 public void run(ApplicationArguments args) {
 pubSubTemplate.subscribe("topico-test-assinatura", msg -> {
           System.out.println("Consumindo mensagem \n" + msg.toString());
 msg.ack();
 });
 }
}


A classe acima implementa ApplicationRunner para que o código no método run() seja executado assim que a aplicação comece a rodar.

Além disso, injetamos a classe PubSubTemplate para consumir as mensagens que chegam ao tópico especificado por meio do método subscribe(). Por fim, o metodo ack(), notifica o serviço do google que a mensagem foi recebida.


Agora que finalizamos a parte do código, vamos a algumas configurações que teremos que fazer no Google Cloud Console.


Isso pode ser feito por um client diretamento do terminal ou no próprio google console. Vou mostrar pelo console.


Após criar um projeto no google console, precisaremos ativar uma chave para autenticação. Para isso, procure por Credentials na barra de busca:





Após entrar nessa sessão, você encontrará uma listas com as contas que estão disponíveis para o seu usuário. Escolha a conta que deseja usar e clique em editar.





Na próxima tela, será exibida a aba CHAVES. Nela terá a opção de adicionar uma nova chave. Clique na opção e será gerado um arquivo com a chave para autenticação no serviço. Faça dowload do arquivo.


Após baixar o arquivo de autenticação, vamos criar uma variável de ambiente com o path do arquivo. Isso pode ser feito de várias formas, inclusive pode ser feito via código ao invés de variável de ambiente. Aqui, vou mostrar como foi feito na IDE Intellij.

Clique em Edit Configurations e em, Environment Variables adicione:

GOOGLE_APPLICATION_CREDENTIALS=[file_path].


Caso não seja especificado um arquivo de autenticação no google ou se a configuração estiver errada, a aplicação não vai nem conseguir iniciar.


Além do arquivo de autenticação, vamos configurar agora o tópico e subscrição que vamos utilizar.

Na barra de busca do Google Console, procure por Pub/Sub:





Após abrir essa seção, clique no botão Criar Tópico e crie um tópico com o nome que você especificou no código.

Depois de criado o tópico, clique em mais ações (3 pontinhos) no lado direito, e crie a assinatura com o mesmo nome especificado no código.



Ótimo, agora sim nossa aplicação já está pronta!!

Vamos subir a aplicação e fazer um POST para o nosso controller:





Após fazer o POST, a saída do console será essa:





Note que após a mensagem ser enviada, imediatamente ela é consumida pela outra ponta.


É isso galera, espero ter contribuído.

Até a próxima!


Posts recentes

Ver tudo