1. Visão geral
A Spring Integration oferece um mecanismo de mensagens para trocar Messages
pelo MessageChannels
. Ele usa adaptadores de canais para se comunicar com sistemas externos.
Neste exercício, criaremos dois aplicativos que se comunicam usando os adaptadores de canal do Spring Integration fornecidos pelo Spring Cloud GCP. Com esses adaptadores, o Spring Integration usa o Google Cloud Pub/Sub como back-end de troca de mensagens.
Depois, também verá como usar o Cloud Shell e o comando gcloud do SDK do Cloud.
Este tutorial usa o exemplo de código do Guia explicativo do Spring Boot.
O que você vai aprender
- Como trocar mensagens entre aplicativos com o Google Cloud Pub/Sub usando a integração do Spring e o Spring Cloud GCP
O que é necessário
- Um projeto do Google Cloud Platform
- Um navegador, como o Chrome ou o Firefox
- Conhecer os editores de texto padrão do Linux, como vim, emacs ou nano
Como você vai usar este tutorial?
Como você classificaria sua experiência com a criação de apps da Web HTML/CSS?
Como você classificaria sua experiência com o uso dos serviços do Google Cloud Platform?
2. Configuração e requisitos
Configuração de ambiente autoguiada
- Faça login no Console do Google Cloud e crie um novo projeto ou reutilize um existente. Crie uma conta do Gmail ou do Google Workspace, se ainda não tiver uma.
- O Nome do projeto é o nome de exibição para os participantes do projeto. É uma string de caracteres não usada pelas APIs do Google e pode ser atualizada quando você quiser.
- O ID do projeto precisa ser exclusivo em todos os projetos do Google Cloud e não pode ser mudado após a definição. O console do Cloud gera automaticamente uma string exclusiva. Em geral, não importa o que seja. Na maioria dos codelabs, é necessário fazer referência ao ID do projeto, normalmente identificado como
PROJECT_ID
. Se você não gostar do ID gerado, crie outro aleatório. Se preferir, teste o seu e confira se ele está disponível. Ele não pode ser mudado após essa etapa e permanece durante o projeto. - Para sua informação, há um terceiro valor, um Número do projeto, que algumas APIs usam. Saiba mais sobre esses três valores na documentação.
- Em seguida, ative o faturamento no console do Cloud para usar os recursos/APIs do Cloud. A execução deste codelab não vai ser muito cara, se tiver algum custo. Para encerrar os recursos e evitar cobranças além deste tutorial, exclua os recursos criados ou exclua o projeto. Novos usuários do Google Cloud estão qualificados para o programa de US$ 300 de avaliação sem custos.
Google Cloud Shell
Embora o Google Cloud possa ser operado remotamente do seu laptop, neste codelab vamos usar o Google Cloud Shell, um ambiente de linha de comando executado no Cloud.
Ativar o Cloud Shell
- No Console do Cloud, clique em Ativar o Cloud Shell.
Se você estiver iniciando o Cloud Shell pela primeira vez, verá uma tela intermediária com a descrição dele. Se aparecer uma tela intermediária, clique em Continuar.
Leva apenas alguns instantes para provisionar e se conectar ao Cloud Shell.
Essa máquina virtual tem todas as ferramentas de desenvolvimento necessárias. Ela oferece um diretório principal persistente de 5 GB, além de ser executada no Google Cloud. Isso aprimora o desempenho e a autenticação da rede. Grande parte do trabalho neste codelab, se não todo, pode ser feito em um navegador.
Depois de se conectar ao Cloud Shell, você verá sua autenticação e o projeto estará configurado com o ID do seu projeto.
- Execute o seguinte comando no Cloud Shell para confirmar se a conta está autenticada:
gcloud auth list
Resposta ao comando
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
- Execute o seguinte comando no Cloud Shell para confirmar que o comando gcloud sabe sobre seu projeto:
gcloud config list project
Resposta ao comando
[core] project = <PROJECT_ID>
Se o projeto não estiver configurado, configure-o usando este comando:
gcloud config set project <PROJECT_ID>
Resposta ao comando
Updated property [core/project].
3. Provisionar recursos do Pub/Sub
Navegue até a página de tópicos do Google Cloud Pub/Sub.
Clique em Criar tópico.
Digite exampleTopic
como o nome do tópico e clique em Criar.
Depois que o tema for criado, permaneça na página "Tópicos". Procure o tópico que você acabou de criar, pressione os três pontos verticais no final da linha e clique em Nova assinatura.
Digite exampleSubscription
na caixa de texto do nome da assinatura e clique em Criar.
4. Inicializar aplicativos Spring Boot
Depois que o Cloud Shell for iniciado, você poderá usar a linha de comando para gerar dois novos aplicativos do Spring Boot com o Spring Initializr:
$ curl https://start.spring.io/starter.tgz \
-d bootVersion=3.0.5 \
-d dependencies=web,integration,cloud-gcp-pubsub \
-d type=maven-project \
-d baseDir=spring-integration-sender | tar -xzvf -
$ curl https://start.spring.io/starter.tgz \
-d bootVersion=3.0.5 \
-d dependencies=web,integration,cloud-gcp-pubsub \
-d type=maven-project \
-d baseDir=spring-integration-receiver | tar -xzvf -
5. Criar um aplicativo para enviar mensagens
Agora, vamos criar nosso aplicativo de envio de mensagens. Mude para o diretório do app de envio.
$ cd spring-integration-sender
Queremos que nosso app escreva mensagens para um canal. Depois que uma mensagem chega ao canal, ela é recebida pelo adaptador de canal de saída, que a converte de uma mensagem genérica do Spring em uma mensagem do Google Cloud Pub/Sub e a publica em um tópico do Google Cloud Pub/Sub.
Para que nosso app grave em um canal, podemos usar um gateway de mensagens da Spring Integration. Usando um editor de texto de vim
, emacs
ou nano
, declare uma interface PubsubOutboundGateway
dentro da classe DemoApplication
.
src/main/java/com/example/demo/DemoApplication.java
...
import org.springframework.integration.annotation.MessagingGateway;
@SpringBootApplication
public class DemoApplication {
...
@MessagingGateway(defaultRequestChannel = "pubsubOutputChannel")
public interface PubsubOutboundGateway {
void sendToPubsub(String text);
}
}
Agora temos um mecanismo para enviar mensagens a um canal, mas para onde essas mensagens vão depois que estão no canal?
Precisamos de um adaptador de canal de saída para consumir novas mensagens no canal e publicá-las em um tópico do Google Cloud Pub/Sub.
src/main/java/com/example/demo/DemoApplication.java
...
import com.google.cloud.spring.pubsub.core.PubSubTemplate;
import com.google.cloud.spring.pubsub.integration.outbound.PubSubMessageHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.messaging.MessageHandler;
@SpringBootApplication
public class DemoApplication {
...
@Bean
@ServiceActivator(inputChannel = "pubsubOutputChannel")
public MessageHandler messageSender(PubSubTemplate pubsubTemplate) {
return new PubSubMessageHandler(pubsubTemplate, "exampleTopic");
}
}
A anotação @ServiceActivator
faz com que esse MessageHandler
seja aplicado a todas as novas mensagens em inputChannel
. Nesse caso, estamos chamando nosso adaptador de canal de saída, PubSubMessageHandler
, para publicar a mensagem no tópico exampleTopic
do Google Cloud Pub/Sub.
Com o adaptador de canal instalado, agora podemos conectar automaticamente um objeto PubsubOutboundGateway
e usá-lo para gravar uma mensagem em um canal.
src/main/java/com/example/demo/DemoApplication.java
...
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.view.RedirectView;
@SpringBootApplication
public class DemoApplication {
...
@Autowired
private PubsubOutboundGateway messagingGateway;
@PostMapping("/postMessage")
public RedirectView postMessage(@RequestParam("message") String message) {
this.messagingGateway.sendToPubsub(message);
return new RedirectView("/");
}
}
Devido à anotação @PostMapping
, agora temos um endpoint que detecta solicitações HTTP POST, mas não sem adicionar também uma anotação @RestController
à classe DemoApplication
para marcá-la como um controlador REST.
src/main/java/com/example/demo/DemoApplication.java
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class DemoApplication {
...
}
Verifique se JAVA_HOME
está definido com a versão correta.
export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64
Execute o app remetente.
# Set the Project ID in environmental variable
$ export GOOGLE_CLOUD_PROJECT=`gcloud config list --format 'value(core.project)'`
$ ./mvnw spring-boot:run
O app ouve solicitações POST que contêm uma mensagem na porta 8080 e no endpoint /postMessage
, mas vamos abordar isso mais tarde.
6. Criar um aplicativo para receber mensagens
Acabamos de criar um app que envia mensagens pelo Google Cloud Pub/Sub. Agora, vamos criar outro app que recebe e processa essas mensagens.
Clique em + para abrir uma nova sessão do Cloud Shell.
Em seguida, na nova sessão do Cloud Shell, altere os diretórios para o diretório do app receptor:
$ cd spring-integration-receiver
No app anterior, a declaração do gateway de mensagens criava o canal de saída. Como não usamos um gateway para receber mensagens, precisamos declarar nosso próprio MessageChannel
, onde as mensagens recebidas vão chegar.
src/main/java/com/example/demo/DemoApplication.java
...
import org.springframework.context.annotation.Bean;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.messaging.MessageChannel;
@SpringBootApplication
public class DemoApplication {
...
@Bean
public MessageChannel pubsubInputChannel() {
return new DirectChannel();
}
}
Vamos precisar do adaptador de canal de entrada para receber mensagens do Google Cloud Pub/Sub e redirecioná-las para pubsubInputChannel
.
src/main/java/com/example/demo/DemoApplication.java
...
import com.google.cloud.spring.pubsub.core.PubSubTemplate;
import com.google.cloud.spring.pubsub.integration.inbound.PubSubInboundChannelAdapter;
import org.springframework.beans.factory.annotation.Qualifier;
@SpringBootApplication
public class DemoApplication {
...
@Bean
public PubSubInboundChannelAdapter messageChannelAdapter(
@Qualifier("pubsubInputChannel") MessageChannel inputChannel,
PubSubTemplate pubSubTemplate) {
PubSubInboundChannelAdapter adapter =
new PubSubInboundChannelAdapter(pubSubTemplate, "exampleSubscription");
adapter.setOutputChannel(inputChannel);
return adapter;
}
}
Esse adaptador se vincula ao pubsubInputChannel
e detecta novas mensagens da assinatura exampleSubscription
do Google Cloud Pub/Sub.
Temos um canal em que as mensagens recebidas são postadas, mas o que fazer com elas?
Vamos processá-las com uma @ServiceActivator
que é acionada quando novas mensagens chegam a pubsubInputChannel
. Neste caso, registraremos apenas o payload da mensagem.
src/main/java/com/example/demo/DemoApplication.java
...
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.integration.annotation.ServiceActivator;
@SpringBootApplication
public class DemoApplication {
...
private static final Log LOGGER = LogFactory.getLog(DemoApplication.class);
@ServiceActivator(inputChannel = "pubsubInputChannel")
public void messageReceiver(String payload) {
LOGGER.info("Message arrived! Payload: " + payload);
}
}
Verifique se JAVA_HOME
está definido com a versão correta.
export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64
Execute o app receptor.
$ ./mvnw spring-boot:run -Dspring-boot.run.jvmArguments="-Dserver.port=8081"
Agora, todas as mensagens que você enviar ao app remetente serão registradas no app receptor. Para testar isso, abra uma nova sessão do Cloud Shell e faça uma solicitação HTTP POST para o app remetente.
$ curl --data "message=Hello world!" localhost:8080/postMessage
Em seguida, verifique se o app receptor registrou a mensagem que você enviou.
INFO: Message arrived! Payload: Hello world!
7. Limpeza
Exclua a assinatura e o tópico criados como parte deste exercício.
$ gcloud pubsub subscriptions delete exampleSubscription
$ gcloud pubsub topics delete exampleTopic
8. Resumo
Configure dois aplicativos do Spring Boot que usam adaptadores de canal da integração do Spring para o Google Cloud Pub/Sub. Eles trocam mensagens entre si sem nunca interagir com a API Google Cloud Pub/Sub.
9. Parabéns!
Você aprendeu a usar os adaptadores de canal da integração do Spring para o Google Cloud Pub/Sub.
Saiba mais
- Google Cloud Pub/Sub: https://cloud.google.com/pubsub/
- Projeto do Spring no GCP: http://cloud.spring.io/spring-cloud-gcp/
- Repositório do GitHub do Spring no GCP: https://github.com/GoogleCloudPlatform/spring-cloud-gcp
- Java no Google Cloud Platform: https://cloud.google.com/java/
Licença
Este conteúdo está sob a licença Atribuição 2.0 Genérica da Creative Commons.