Sobre este codelab
1. Visão geral
A integração do Spring fornece a você um mecanismo de mensagens para trocar Messages
por MessageChannels
. Ele usa adaptadores de canal para se comunicar com sistemas externos.
Neste exercício, criaremos dois apps que se comunicam usando os adaptadores de canal do Spring Integration fornecidos pelo Spring Cloud GCP. Esses adaptadores fazem com que a integração do Spring 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.
Neste tutorial, usamos o código de exemplo do Guia de primeiros passos da Spring Boot.
O que você aprenderá
- Como trocar mensagens entre apps com o Google Cloud Pub/Sub usando a integração e o GCP do Spring Cloud
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ê 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 personalizada
Se você ainda não tem uma Conta do Google (Gmail ou Google Apps), crie uma. Faça login no Console do Google Cloud Platform (console.cloud.google.com) e crie um novo projeto:
Lembre-se do código do projeto, um nome exclusivo em todos os projetos do Google Cloud. O nome acima já foi escolhido e não servirá para você. Faremos referência a ele mais adiante neste codelab como PROJECT_ID
.
Em seguida, você precisará ativar o faturamento no Console do Cloud para usar os recursos do Google Cloud.
A execução por meio deste codelab terá um custo baixo, mas poderá ser mais se você decidir usar mais recursos ou se deixá-los em execução. Consulte a seção "limpeza" no final deste documento.
Novos usuários do Google Cloud Platform estão qualificados para um teste sem custo financeiro de US$300.
Google Cloud Shell
Embora o Google Cloud possa ser operado remotamente do seu laptop, neste codelab usaremos o Google Cloud Shell, um ambiente de linha de comando executado no Cloud.
Ativa o Google Cloud Shell
No Console do GCP, clique no ícone do Cloud Shell na barra de ferramentas localizada no canto superior direito:
Em seguida, clique em "Start Cloud Shell":
O provisionamento e a conexão ao ambiente levarão apenas alguns instantes para serem concluídos:
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. Praticamente todo o seu trabalho neste laboratório pode ser feito em um navegador ou no seu Google Chromebook.
Depois que você se conectar ao Cloud Shell, sua autenticação já terá sido feita, e o projeto estará definido com seu PROJECT_ID.
Execute o seguinte comando no Cloud Shell para confirmar se a conta está autenticada:
gcloud auth list
Resposta ao comando
Credentialed accounts: - <myaccount>@<mydomain>.com (active)
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
Navegue até a página de tópicos do Google Cloud Pub/Sub e ative a API.
Clique em Criar tópico.
Digite exampleTopic
como o nome do tópico e clique em Criar.
Após a criação do tópico, permaneça na página de tópicos. Procure o tópico que você criou, 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 de inicialização do Spring
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=2.0.6.RELEASE \
-d dependencies=web \
-d baseDir=spring-integration-sender | tar -xzvf -
$ curl https://start.spring.io/starter.tgz \
-d bootVersion=2.0.6.RELEASE \
-d baseDir=spring-integration-receiver | tar -xzvf -
5. Criar um aplicativo para enviar mensagens
Agora, vamos criar o app de envio de mensagens. Mude para o diretório dele.
$ cd spring-integration-sender
Queremos que nosso app grave mensagens em um canal. Depois que uma mensagem é encontrada no canal, ela é recebida pelo adaptador do canal de saída, que a converte em uma mensagem Spring genérica 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 de integração do Spring (em inglês). 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 (em inglês)
...
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 ficam no canal?
Precisamos de um adaptador de canais 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 (em inglês)
...
import org.springframework.cloud.gcp.pubsub.core.PubSubTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.cloud.gcp.pubsub.integration.outbound.PubSubMessageHandler;
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 canais de saída, PubSubMessageHandler
, para publicar a mensagem no tópico exampleTopic
do Google Cloud Pub/Sub.
Com o adaptador de canais ativado, podemos conectar um objeto PubsubOutboundGateway
automaticamente e usá-lo para escrever uma mensagem em um canal.
src/main/java/com/example/demo/DemoApplication.java (em inglês)
...
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 POST HTTP, 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 (em inglês)
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class DemoApplication {
...
}
Para que o app seja executado, basta adicionar as dependências necessárias.
pom.xml (link em inglês)
<project>
...
<!-- Add Spring Cloud GCP Dependency BOM -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-dependencies</artifactId>
<version>1.0.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
...
<!-- Add Pub/Sub Starter -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-pubsub</artifactId>
</dependency>
<!-- Add Spring Integration -->
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
</dependency>
</dependencies>
</project>
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 está ouvindo solicitações POST que contêm uma mensagem na porta 8080 e no endpoint /postMessage
, mas falaremos sobre isso mais tarde.
6. Criar um aplicativo para receber mensagens
Acabamos de criar um app que envia mensagens pelo Google Cloud Pub/Sub. Agora, criaremos 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, 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 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
onde as mensagens recebidas chegarão.
src/main/java/com/example/demo/DemoApplication.java (em inglês)
...
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();
}
}
O adaptador de canal de entrada precisará receber mensagens do Google Cloud Pub/Sub e redirecioná-las para pubsubInputChannel
.
src/main/java/com/example/demo/DemoApplication.java (em inglês)
...
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cloud.gcp.pubsub.core.PubSubTemplate;
import org.springframework.cloud.gcp.pubsub.integration.inbound.PubSubInboundChannelAdapter;
@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á-los com um @ServiceActivator
que é acionado quando novas mensagens chegam a pubsubInputChannel
.
src/main/java/com/example/demo/DemoApplication.java (em inglês)
...
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);
}
}
Nesse caso, vamos registrar o payload da mensagem.
Precisamos adicionar as dependências necessárias.
pom.xml (link em inglês)
<project>
...
<!-- Add Spring Cloud GCP Dependency BOM -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-dependencies</artifactId>
<version>1.0.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
...
<!-- Add Pub/Sub Starter -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-pubsub</artifactId>
</dependency>
<!-- Add Spring Integration -->
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
</dependency>
</dependencies>
</project>
Execute o app receptor.
$ ./mvnw spring-boot:run
Agora todas as mensagens que você enviar para o app remetente serão registradas no app receptor. Para testar, abra uma nova sessão do Cloud Shell e faça uma solicitação HTTP POST ao 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 beta pubsub subscriptions delete exampleSubscription
$ gcloud beta pubsub topics delete exampleTopic
8. Resumo
Configure dois apps de inicialização do Spring que usam os adaptadores do canal de integração do Spring 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 do Spring Integration para o Google Cloud Pub/Sub.
Saiba mais
- Google Cloud Pub/Sub: https://cloud.google.com/pubsub/
- Projeto do Spring on GCP: http://cloud.spring.io/spring-cloud-gcp/
- Repositório do Spring no GCP do GitHub: https://github.com/spring-cloud/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.