Participe da Maratona Behind the Code! A competição de programação que mais te desafia! Inscreva-se aqui

Realize o desafio de codificação do app do sistema de mensagens IBM MQ

Entre de cabeça e veja como uma solução do sistema de mensagens do mundo real pode ser simples.

Siga as instruções passo a passo para desenvolver um app de sistema de mensagens que interage com um gerenciador de filas e apps que nós fornecemos em um contêiner. Ao longo do processo, você dominará novos conceitos de sistema de mensagens e aptidões que serão necessários para passar no quiz para ganhar o badge do IBM MQ Developer Essentials.

Pré-requisitos

Para concluir este desafio, serão necessários os seguintes itens em seu ambiente local:

  • Java Development Kit (JDK) para desenvolver e executar aplicativos
  • Classes JMS, no arquivo JMS.jar
  • Classes IBM e IBM MQ para JMS, no arquivo com.ibm.mq.allclient.jar
  • A amostra JmsPutGet.java
  • Código de amostra para este MQ Developer Challenge, no mq-dev-badge-sample

O desafio

Parabéns! Você acabou de iniciar uma nova tarefa como um desenvolvedor para um revendedor de ingressos para conferências.

A liderança de sua equipe o incumbiu de criar um aplicativo de sistema de mensagens que se integra a um serviço de reserva de ingressos do MQ e automatiza o processo de alocação do ingresso. Isso garantirá que sua nova organização acompanhe o ritmo das demandas do cliente. Nós já criamos o serviço de reserva do evento, inclusive um gerenciador de filas, e o disponibilizamos como uma imagem do Docker. Você precisa apenas criar a imagem e executá-la.

Em seguida, para este desafio, você codificará o aplicativo do revendedor. Nós fornecemos um modelo de aplicativo Java no GitHub com comentários e stubs de código. Você precisa apenas preencher as lacunas codificando o JMS e as partes de processamento de mensagens do cenário.

Seu código irá:

  • Conectar-se a um gerenciador de filas (aquele que nós fornecemos)
  • Assinar o tópico newTickets
  • Enviar uma mensagem de solicitação para comprar um lote de ingressos, configurar um destino de resposta e uma validade de mensagem de 15 minutos (nós não desejamos nos comprometer com uma compra indefinidamente)
  • Obter uma mensagem de resposta da fila de confirmação especificada como o destino de resposta
  • Imprimir o resultado

Para que você não fique preso muito tempo em um processo, nós incluímos uma folha de dicas e anexamos um modelo de resposta para referência.

Nós fornecemos três maneiras de participar do desafio:

  1. Gravar o código imediatamente, à medida que você avança
  2. Revisar o aplicativo de resposta do modelo
  3. Participar da correção de um defeito simples

Arquitetura do serviço de sistema de mensagens do aplicativo do cliente

Quando os ingressos são disponibilizados para venda, o serviço terceirizado gera uma mensagem do revendedor para notificar seus assinantes (é você!).

Os revendedores de ingresso, então, solicitam um lote de ingressos para o evento conferência. Assim que os ingressos são alocados, o revendedor tem a liberdade de distribuir aos seus clientes.

Vamos dar uma olhada no diagrama da arquitetura. Você criará o aplicativo do revendedor.

Diagrama da arquitetura para o app do sistema de mensagens do revendedor

As mensagens são publicadas no tópico newTickets a cada 30 segundos pelo serviço de reserva do evento.

A carga útil da mensagem contém um EventId e o número de ingressos disponíveis.

O aplicativo do Revendedor usa a carga útil recebida para construir uma mensagem de solicitação. Por fim, o serviço de reserva consome da fila de compra e responde a cada mensagem no destino JMSReplyTo (fila de confirmação) com uma carga útil configurada, conforme a seguir:

Aceito - <number_of_tickets_allocated> ou Rejeitado - Vendido

Destacando o app do sistema de mensagens do cliente que você criará

Você está criando o app do revendedor de ingressos, que é um aplicativo cliente do IBM MQ.

Para ajudá-lo a focar em seu MVP (produto mínimo viável), este diagrama mostra os elementos do app IBM MQ JMS que você precisa criar em relação ao servidor MQ e ao serviço do revendedor que você forneceu em um contêiner do Docker. As ações do aplicativo cliente principal são nomeadas e numeradas.

Diagrama do aplicativo cliente do MQ

Quando você tiver concluído a codificação de seu aplicativo, seu aplicativo irá:

  1. Conectar-se a um gerenciador de filas
  2. Assinar um tópico
    • Receber uma publicação
    • Processar uma publicação
    • Ao receber uma publicação, crie e envie uma mensagem de solicitação à fila de compra para comprar zero ou mais ingressos. A mensagem de solicitação possui propriedades:
      • diz quantos ingressos pedir
      • para um determinado EventID
      • configura um destino de resposta para a confirmação (a resposta)
      • configura a validade da mensagem para 15 minutos
  3. Coloca a mensagem de solicitação em uma fila de compra (pedido)
    • (O app do coordenador da compra de ingresso faz uma obtenção nessa fila)
    • (Processa a mensagem e aloca um número de ingressos, se houver algum disponível)
    • (Coloca uma mensagem na fila de confirmação (resposta). A mensagem de resposta possui propriedades:
      • diz quantos ingressos foram alocados, se houver
      • para um determinado EventID
  4. Faz uma obtenção na fila de resposta
  5. Imprime quantos ingressos do evento tiverem sido comprados

É necessário que o app do sistema de mensagens tenha o seguinte comportamento:

  • Lidar com uma mensagem publicada no tópico newTickets a cada 30 segundos.
  • Fornecer o prompt para perguntar ao usuário quantos dos ingressos disponíveis ele deseja comprar.
  • Lidar com a resposta que o serviço de reserva do evento de conferência fornece após o processamento de sua mensagem de solicitação.
  • Imprimir o resultado da resposta para stdout.

Verifique seus pré-requisitos

Primeiro, vamos verificar se você tem o Java Development Kit instalado. Emita este comando:

java -version

Você deverá ver uma saída semelhante a:

saída do comando da versão Java

É necessário ter o JDK 8, 1.8.n_nnn.

Se você não tiver o Java instalado, acesse a página OpenJDK, selecione OpenJDK 8 e sua plataforma. Em algumas plataformas, é possível extrair e instalá-lo usando a linha de comandos. Apenas certifique-se de obter o JDK (Java Development Kit) para desenvolvimento, não apenas o JRE (Java Runtime Environment).

Se você concluiu o tutorial Desenvolva um app JMS ponto a ponto, já deve ter o JDK (Java Development Kit) e o diretório MQClient com os arquivos com.ibm.mq.allclient.jar e javax.jms-api-2.0.1.jar. Você precisará desses arquivos .jar para executar o app do desafio. Se você tem o JDK e os arquivos .jar no diretório MQClient, poderá ir para a próxima etapa, obtendo o código do desafio.

Se você não concluiu esse tutorial, vamos ajudá-lo a se preparar:

  1. Crie um diretório MQClient para salvar os arquivos necessários para a amostra, por exemplo, em seu diretório inicial:

     mkdir MQClient
    
  2. No diretório MQClient, extraia o arquivo com.ibm.mq.allclient.jar usando curl.

     curl -o com.ibm.mq.allclient-9.1.4.0.jar https://repo1.maven.org/maven2/com/ibm/mq/com.ibm.mq.allclient/9.1.4.0/com.ibm.mq.allclient-9.1.4.0.jar
    
  3. Na pasta MQClient, extraia o arquivo .jar do JMS usando curl.

     curl -o javax.jms-api-2.0.1.jar https://repo1.maven.org/maven2/javax/jms/javax.jms-api/2.0.1/javax.jms-api-2.0.1.jar
    

Obtenha o código do desafio

É necessário fazer o download do código de desafio do badge, que é armazenado no ibm/messaging/mq-dev-badge-sample repositório Github. Acesse nosso repositório ibm/messaging/mq-dev-badge-sample no Github e clique no botão clonar ou fazer download. É possível optar por Clonar com SSH, Usar HTTPS ou Fazer download do ZIP com o código. Clone ou descompacte o repositório no diretório MQClient.

  1. Quando você tiver o código localmente, mude para o diretório do Código de amostra:

    cd mq-dev-badge-sample

  2. Execute o comando print-working-directory para certificar-se de que você está no local correto:

    pwd

    O final do seu caminho deverá estar assim:

    ~/MQClient/mq-dev-badge-sample

  3. Digite ls para listar o conteúdo do diretório:

    ls

    Deverá aparecer os seguintes diretórios e arquivos:

    ├-- MQTicketService │ ├-- Dockerfile │ . │ . │ └-- TicketGenerator ├-- ModelAnswer ├-- ModelAnswerWithDefectToFix └-- TicketReseller

O diretório MQTicketService possui o Dockerfile com a definição para criar uma imagem e ativar um contêiner com o servidor MQ (gerenciador de filas). Ele também possui o TicketGenerator com o código Java para os apps/serviços que irão com o seu app quando ele for codificado e executado. Os apps do lado do servidor são iniciados dentro do contêiner ao mesmo tempo que o gerenciador de filas.

Ativando o sistema de Reserva de Eventos

Antes de começar a codificar seu app do revendedor, vamos ver como o lado do servidor ou o serviço de reserva de eventos funciona.

Primeiro, nós criaremos uma imagem do Docker e executaremos o contêiner com o MQ e o app que publica a disponibilidade do ingresso e responde às solicitações de seu app.

Se ele estiver funcionando, vamos deixar que ele encerre e depois, quando estivermos prontos para testar o app do desafio, vamos reiniciá-lo.

Siga estas etapas para ativar o serviço de reserva de eventos:

  1. De dentro do diretório mq-dev-badge-sample, mude para o diretório MQTicketService:

     cd MQTicketService
    
  2. Nosso Dockerfile neste local tem tudo definido para executar o MQ dentro do contêiner, além de executar os apps de publicador e de resposta. Execute o comando para criar a imagem:

     docker build . -t mqbadge:latest
    
  3. O Docker extrairá todos os pré-requisitos e criará a imagem. Quando ele concluir, verifique se você tem a imagem criada mqbadge:

     docker images
    

    Você verá: Saída do comando docker images

  4. Execute o contêiner na imagem:

     docker run -e LICENSE=accept -e MQ_QMGR_NAME=QM1 -e LOG_FORMAT=json -e MQ_APP_PASSWORD=passw0rd -p 1414:1414 -p 9443:9443 -ti --name mqebs mqbadge:latest
    

    Logo em seguida, a saída do contêiner é iniciada em sua linha de comandos. Preste atenção nos eventos que começam a ser publicados: Saída da execução das imagens do Docker

O sistema de reserva de eventos agora está em execução dentro do contêiner. Observe que o contêiner foi iniciado sem a opção --detach, para que os logs sejam exibidos na tela enquanto o contêiner está em execução.

O processo de contêiner inclui:

  • O app publicador, que envia uma publicação sobre ingressos disponíveis a cada 30 segundos
  • O coordenador de compra do ingresso, que processa os pedidos de compra e aloca um lote de ingressos. Importante: este é o núcleo do negócio de reserva de eventos no qual os pedidos de compras são processados e os ingressos são alocados. O IBM MQ Messaging desempenha um papel crucial dentro do código de processamento de eventos de conferência, fornecendo a entrega garantida de mensagens com alto valor entre o serviço de reserva de eventos de conferência e os revendedores de ingressos. É fundamental que o negócio de reserva de eventos de conferências faça isso corretamente, pois vender ingressos em excesso ou não conseguir atender às solicitações seria prejudicial para a sua reputação.
  • Servidor do IBM MQ, que é o gerenciador de filas que hospeda o tópico de assinatura newTickets, a fila de compras para mensagens de solicitação e a fila de confirmação para mensagens de resposta.

As filas foram criadas administrativamente executando comandos do MQSC quando o contêiner do Docker iniciou.

Os objetos da fila também podem ser criados com o MQ Console, usando a interface REST do MQ ou programaticamente.

Agora, você está pronto para começar a desenvolver seu aplicativo revendedor. Mas primeiro, vamos ver como o app ModelAnswer funciona com o serviço de registro de eventos.

Execute o app ModelAnswer para vê-lo em ação

Abra outro terminal e mude para o diretório MQClient/mq-dev-badge-sample/ModelAnswer.

Nesse diretório, execute o comando para compilar o aplicativo:

javac -cp ../../com.ibm.mq.allclient-9.1.4.0.jar:../../javax.jms-api-2.0.1.jar com/ibm/mq/demo/*.java

Este comando funciona apenas se você tiver os arquivos .jar no diretório MQClient. Consulte as seções Verifique seus pré-requisitos e Obtenha o código do desafio para assegurar que seu código esteja configurado corretamente.

Verifique se o app foi compilado corretamente analisando os arquivos:

`ls com/ibm/mq/demo`

Você deverá ver as classes compiladas juntamente com os arquivos Java:

Saída do diretório de app compilado

Volte para a janela do terminal original na qual o contêiner com o serviço foi interrompido.

Organize as duas janelas do terminal lado a lado para que você possa interagir facilmente com ambas.

duas janelas do terminal lado a lado

No terminal do contêiner do Docker à esquerda, é necessário reiniciar o contêiner e ver a saída do servidor e o app em execução. Inicie o contêiner:

```
docker restart mqebs
```

Obtenha a saída do contêiner no terminal:

```
docker container attach mqebs
```

No terminal à direita, prepare o comando para executar o aplicativo ModelAnswer, mas aguarde os eventos no terminal do servidor começarem a aparecer antes de inserir o comando:

```
java -cp ../../com.ibm.mq.allclient-9.1.4.0.jar:../../javax.jms-api-2.0.1.jar:. com.ibm.mq.demo.Reseller
```

duas janelas do terminal lado a lado com comandos

Agora, quando você executa o comando para iniciar o aplicativo ModelAnswer, você deverá ver:

duas janelas do terminal lado a lado com comandos

Assim que o próximo conjunto de ingressos disponíveis for publicado, o prompt deverá aparecer no terminal ModelAnswer solicitando o número de ingressos que você deseja garantir:

duas janelas do terminal lado a lado com comandos

Insira um número de ingressos que você deseja reservar no terminal do app ModelAnswer. Você deverá ver as mensagens de troca em ambos os terminais.

duas janelas do terminal lado a lado com comandos

O contêiner será encerrado quando não houver mais eventos de ingresso para publicar.

duas janelas do terminal lado a lado com comandos

O app ModelAnswer não será encerrado até que você insira um número de ingressos para o último evento anunciado. Em seguida, o app deverá se desconectar, porque os apps no contêiner também foram desconectados e o gerenciador de filas do MQ interrompeu encadeamentos e encerrou conexões.

duas janelas do terminal lado a lado com comandos

Agora que você viu como o app e o serviço interagem, vá em frente e grave seu próprio código Java no diretório TicketReseller ou corrija o defeito e faça com que tudo funcione no diretório ModelAnswerWithDefectToFix.

Codificando seu aplicativo de revendedor

Por conveniência, talvez você deseje usar IDE Java como o Eclipse. Como alternativa, é possível desenvolver seu código em seu editor favorito, como o Atom.

No editor de sua escolha, abra o diretório TicketReseller ou o ModelAnswerWithDefectToFix.

O Código de amostra é dividido em diversas classes. Para concluir o desafio, é necessário fazer atualizações de código nessas classes:

  • SessionBuilder.java
  • TicketSubscriber.java
  • TicketRequester.java

Os comentários nos stubs dessas classes devem orientá-lo quanto ao que precisa ser feito. Consulte as seções anteriores para saber o que seu aplicativo precisa fazer, para ajudar na compilação, e para obter exemplos de como os apps funcionam.

Precisa depurar?

Algo deu errado? Dê uma olhada na folha de dicas.

Aprimorando seu aplicativo

Para saber mais sobre os aplicativos do sistema de mensagens do cliente prontas para produção, é necessário considerar a segurança e a persistência de mensagem. Você também pode considerar a transacionalidade de suas mensagens.

Por que usar o sistema de mensagens?

O sistema de evento de conferência e os aplicativos de revendedor são fracamente acoplados. O sistema de mensagens assíncrono nos permite integrar esses componentes e criar em um buffer ou amortecedor. Caso algum componente perca a conectividade, falhe ou passe por flutuações no rendimento, a camada do sistema de mensagens lidará com qualquer instabilidade. Nosso código do aplicativo é simplificado, pois a camada do sistema de mensagens cuida da parte difícil, como a segurança, a recuperação e a persistência da troca de mensagens entre os componentes.

A API do sistema de mensagens fornece uma estrutura para que a lógica do nosso aplicativo de revendedor seja conduzida quando uma mensagem for entregue, em vez de pesquisar continuamente o servidor para checar o trabalho. Isso remove o carregamento desnecessário da rede e do aplicativo de evento de conferência. O IBM MQ permite que a solução seja escalada à medida que a demanda aumentar.

Estilo do sistema de mensagens de publicação/assinatura

A publicação/assinatura é um dos estilos de sistema de mensagens que o IBM MQ implementa. O outro é o ponto a ponto. No ponto a ponto, as mensagens são trocadas entre duos aplicativos únicas. Na publicação/assinatura, um ou muitos publicadores podem publicar para um ou muitos assinantes em um tópico.

O estilo de sistema de mensagens de publicação/assinatura é implementado em nossa solução da seguinte forma: Estilo do sistema de mensagens de publicação/assinatura para esta solução do sistema de mensagens

O serviço de reserva de eventos é o publicador e seu app do revendedor é um dos assinantes. Vamos falar dos outros componentes neste estilo de sistema de mensagens:

  • Tópicos são objetos e eles têm propriedades.
  • A principal propriedade de um tópico é uma sequência de tópicos.
  • As mensagens são publicadas em uma sequência de tópicos por um publicador.
  • Cada publicação é para uma única sequência de tópicos. Os assinantes registram um interesse em, ou assinam, uma sequência de tópicos.
  • Quando um publicador publica uma mensagem em uma sequência de tópicos, um ou mais assinantes dessa sequência de tópicos recebem a mensagem de publicação.
  • Um aplicativo JMS pode usar o objeto de destino JMS que mapeia para um tópico da mesma maneira que ele usaria o destino para mapear para uma fila em um cenário ponto a ponto. Para que a publicação chegue ao assinante com êxito, o publicador e o assinante devem corresponder à mesma sequência de tópicos. O assinante obterá publicações apenas a partir do momento em que ele assina um tópico.
  • Se uma publicação foi enviada antes da assinatura ser criada por um aplicativo específico, esse aplicativo não a receberá.

Padrão do sistema de mensagens de solicitação/resposta

Solicitação de resposta ou solicitação de réplica é um padrão de integração ou do sistema de mensagens no qual o aplicativo que envia uma mensagem para outro aplicativo, requer uma resposta de algum tipo do aplicativo de recebimento. Isso, geralmente, é baseado no estilo de sistema de mensagens ponto a ponto e pode ser síncrono (o aplicativo de envio aguarda a resposta antes de atingir tempo limite) e assíncrono (também chamado de solicitação/retorno de chamada, em que o aplicativo de envio se desconecta, mas estabelece um retorno de chamada para lidar com uma resposta).

Seu app do revendedor é o app emissor e o serviço de reserva de eventos é o app receptor. Estilo do sistema de mensagens de publicação/assinatura para esta solução do sistema de mensagens

O aplicativo de envio geralmente configura um destino de resposta e um ID de correlação para que uma resposta possa voltar para o aplicativo emissor correto.

Para o serviço de reserva de eventos, o destino de resposta foi definido administrativamente no gerenciador de filas. No entanto, o solicitante poderia criar dinamicamente um destino provisório a partir de sua sessão do JMS para concluir a troca.

Protegendo seu aplicativo

Descubra como é possível configurar seu gerenciador de filas e seu aplicativo cliente para usar TLS para criptografar mensagens à medida que elas fluem , pela Internet, entre o servidor e o cliente.

Configurando a persistência de mensagem em seu aplicativo

É importante considerar a persistência de mensagem ao projetar um aplicativo. O IBM MQ suporta sistemas de mensagens persistente e não persistente. Em nosso cenário de reserva de eventos, nós usamos o sistema de mensagens persistente como a configuração padrão nas filas MQ predefinidas.

Criticamente, no caso de uma indisponibilidade do sistema, as mensagens não persistentes podem ser perdidas após a recuperação. Embora, na maioria dos casos, o sistema de mensagens não persistente possa fornecer troca de mensagens mais rápida, ele não é a solução ideal para todos os aplicativos.

Por exemplo, a persistência pode ser importante para uma mensagem de alto valor, mas não tão importante para um cenário no qual mensagens de informação são transmitidas continuamente. No último caso, o design do sistema pode tolerar algum nível de perda de mensagem.

Você pode ler mais sobre persistência de mensagem no IBM MQ Knowledge Center.

E quanto à transacionalidade de minhas mensagens?

Geralmente, os aplicativos de produção são mais sofisticados do que nossa amostra, com cada interação envolvendo diversos recursos, como mensagens ou atualizações de banco de dados, sendo coordenados como uma única operação atômica. Dizem que os recursos que são gerenciados dessa maneira ocorrem dentro de uma unidade de trabalho ou de uma transação.

Por exemplo, uma transação bancária simples pode exigir que seja debitado US$100 de uma conta e creditado o mesmo valor de outra. Um coordenador transacional é usado para assegurar que ambas as operações sejam concluídas com sucesso, ou que nenhuma delas seja concluída de forma alguma.

À medida que a complexidade do aplicativo aumenta, as estruturas de escala corporativa são usadas para coordenar transações entre diversos aplicativos ou sistemas back-end. Estruturas de escala corporativa como essas, fornecidas por:

Focando no desempenho do app

Se você deseja certificar-se de que seu aplicativo irá executar bem e de maneira confiável, dê uma olhada nessas melhores práticas para desenvolvedores.

Resumo e próximas etapas

Parabéns! Você conferiu nosso repositório do GitHub com três maneiras de participar de nossa amostra. Não deixe de conferir a [folha de dicas] do MQ(/articles/mq-dev-cheat­-sheet/), pois ela está repleta de truques ninjas que todo desenvolvedor do MQ deve conhecer.

Se você já concluiu tudo e está pronto para fazer o quiz e ganhar seu badge MQ Developer Essentials, volte para a página badge do IBM MQ Developer Essentials e clique para fazer o quiz!

Aviso

O conteúdo apresentado aqui foi traduzido da página do IBM Developer nos EUA. É possível conferir o conteúdo original em este link.