1. Visão geral
A Spring Integration oferece um mecanismo de mensagens para trocar Messages por MessageChannels. Ela usa adaptadores de canal para se comunicar com sistemas externos.
Neste exercício, vamos criar dois apps que se comunicam usando os adaptadores de canal da Spring Integration fornecidos pelo Spring Cloud GCP. Esses adaptadores fazem com que a Spring Integration use 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 de primeiros passos do Spring Boot.
O que você vai aprender
- Como trocar mensagens entre apps com o Google Cloud Pub/Sub usando a Spring Integration 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 em 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 esta for a primeira vez que você inicia o Cloud Shell, uma tela intermediária será exibida descrevendo o que ele é. Se você recebeu uma tela intermediária, clique em Continuar.

Leva apenas alguns instantes para provisionar e se conectar ao Cloud Shell.

Essa máquina virtual contém 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. Neste codelab, quase todo o trabalho pode ser feito com um navegador.
Depois de se conectar ao Cloud Shell, você vai ver que sua conta está autenticada e que o projeto está configurado com seu ID do 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 comando a seguir no Cloud Shell para confirmar se 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, faça a configuração usando este comando:
gcloud config set project <PROJECT_ID>
Resposta ao comando
Updated property [core/project].
3. Provisionar recursos do Pub/Sub
Acesse 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 tópico 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, use a linha de comando para gerar dois novos aplicativos 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 app de envio de mensagens. Mude para o diretório do app de envio.
$ cd spring-integration-sender
Queremos que nosso app grave mensagens em um canal. Depois que uma mensagem estiver no canal, ela será selecionada pelo adaptador de canal de saída, que a converte de uma mensagem genérica do Spring para 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 de estarem 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 no lugar, 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 está escutando 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 para a versão correta.
export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64
Execute o app do 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 está escutando solicitações POST que contêm uma mensagem na porta 8080 e no endpoint /postMessage, mas vamos chegar a 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 essas mensagens e as processa.
Clique em + para abrir uma nova sessão do Cloud Shell.

Em seguida, na nova sessão do Cloud Shell, mude os diretórios para o diretório do app receptor:
$ cd spring-integration-receiver
No app anterior, a declaração do gateway de mensagens criou o canal de saída para nós. Como não usamos um gateway de mensagens para receber mensagens, precisamos declarar nosso próprio MessageChannel, em que 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();
}
}
Precisaremos do adaptador de canal de entrada para receber mensagens do Google Cloud Pub/Sub e retransmiti-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 escuta 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 essas mensagens?
Vamos processá-las com um @ServiceActivator que é acionado quando novas mensagens chegam ao pubsubInputChannel. Nesse caso, vamos apenas registrar 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 para 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 enviadas ao app do 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 do remetente.
$ curl --data "message=Hello world!" localhost:8080/postMessage
Em seguida, verifique se o app receptor registrou a mensagem enviada.
INFO: Message arrived! Payload: Hello world!
7. Revisão dos dados
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
Você configurou dois apps Spring Boot que usam os adaptadores de canal da Spring Integration para o Google Cloud Pub/Sub. Eles trocam mensagens entre si sem interagir com a API Google Cloud Pub/Sub.
9. Parabéns!
Você aprendeu a usar os adaptadores de canal da Spring Integration para o Google Cloud Pub/Sub.
Saiba mais
- Google Cloud Pub/Sub: https://cloud.google.com/pubsub/
- Projeto Spring no GCP: http://cloud.spring.io/spring-cloud-gcp/
- Repositório do Spring no GCP no GitHub: 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.