Páginas filhas
  • 3.2 Adapters de Recebimento

Versões comparadas

Chave

  • Esta linha foi adicionada.
  • Esta linha foi removida.
  • A formatação mudou.

Tempo aproximado para leitura: 00 min

01. Apresentação

Este documento tem por objetivo apresentar as responsabilidades dos adapters de recebimento de Mensagens Padronizadas TOTVS.

02. Responsabilidades

Os Adapters de recebimento de mensagens são responsáveis por manipular o conteúdo recebido (BusinessContent), transformando no modelo de parâmetro esperado pelo serviço interno, processando o mesmo e retornando o resultado (ReturnContent) ao EAI para que seja enviado ao aplicativo integrado.

Dentre as diversas necessidades de integração, listamos a seguir dois fluxos comuns de integração que são o de processamento e de consulta de dados.

Fluxo de mensagem de processamento

O diagrama abaixo apresenta de forma macro a série de eventos que ocorrem durante o um possível fluxo de processamento de uma mensagem síncrona recebida, exemplificando com a chamada a um Module, mas também se aplica ao consumo de DataServers, Subscribers ou qualquer outro objeto de negócio. Um exemplo de processo de integração que segue este fluxo é a mensagem CancelRequest, que realiza o cancelamento de movimentos.

draw.io Diagram
bordertrue
viewerToolbartrue
fitWindowfalse
diagramNameAdapterReceive
simpleViewerfalse
diagramWidth686
revision3

Fluxo de mensagem de consulta

O diagrama abaixo, de forma similar ao anterior, apresenta o fluxo de processamento de uma mensagem síncrona de consulta de dados.

draw.io Diagram
bordertrue
viewerToolbartrue
fitWindowfalse
diagramNameAdapterReceiveConsulta
simpleViewerfalse
width
diagramWidth

608

686
revision

1

2

Principais funções do adapter de recebimento

  1. Gerar Transformar o conteúdo dado de negócio da mensagem a enviar (BusinessContentrecebido (BusinessContent) e orquestrar a chamada dos objetos de negócio (Servers).
    1. O adapter é responsável por implementar os padrões apresentados anteriormente, transformando o formato do dado original, enriquecendo ou empobrecendo o mesmo, além de realizar as validações necessárias.
    2. Após o adapter encaminhar ao EAI o dado de negócio (BusinessContent), todo o fluxo de envelopamento, salvamento na fila de mensagens e envio ao destinatário é de responsabilidade do EAI.
    3. interpretar os dados recebidos e transformar no modelo esperado pela interface do Server que será consumido.
      1. Exemplo: Ao receber uma mensagem de Request, o adapter deve transcrever o BusinessContent na classe de parâmetros do Subscriber e realizar a chamada ao Módule.
  2. Interpretar o processamento e gerar o objeto com as informações Transformar e/ou processar as informações de negócio da resposta (ReturnContent).
    1. Em integrações para consulta de dados a mensagem de resposta deve ser transformada do formato da Mensagem Padronizada TOTVS para o modelo de retorno, esperado pelo módulo que originou a mensagem.
      1. Ex.: Mensagens de consulta de informações devem transformar o dado recebido antes de encaminhar para o módulo de consulta.
    2. É responsabilidade do adapter gerar o ReturnContent que será retornado ao aplicativo integrado.
      1. Exemplo: A mensagem de consulta de saldos e custos é responsável por buscar as informações no Módule interno ao sistema e converter para o objeto no formato da Mensagem Padronizada TOTVS.
      2. Exemplo 2: A mensagem de cadastro de produtos possui em seu ReturnContent uma propriedade que trafega a lista de De-Paras, que deve ser preenchida pelo Adapter
      Caso a mensagem trafegada demande algum processamento de responsabilidade da camada de integração, este deve ser implementado no método correspondente do adapter.
      1. Ex.: Mensagens de cadastro devem ter o De-Para armazenado na base de dados.
      2. Ex2.: Mensagens assíncronas que devam desbloquear o registro no momento do retorno de sucesso.

03. Implementação de um adapter de

envio

recebimento

Para que uma classe seja um adapter de recebimento de enviomensagens, deve-se atender aos pré-requisitos listados abaixo e realizar as funções de integração listadas anteriormente.

Pré-requisitos

  1. Implementar a interface IAdapterSend IAdapterReceive, implementando em cada método a sua respectiva responsabilidade, internamente a um projeto cuja Dll gerada siga o padrão "RM.*.TotvsMessage.Adapter.dll".

    1. InitializeAdapter - Método responsável pela inicialização do Adapter, recebendo o contexto de execução por referência.

    2. CanExecute ChangeRMContext - Método que permite ao adapter realizar verificações e informar se a mensagem deve ser processada, ignorada ou gerar exceção.

    3. Prepare - Método responsável por retornar ao EAI o BusinessContent a ser enviado ao destinatário, juntamente com outras demandas específicas de negócio.

    4. deve ser utilizado para compor o RMSContext a partir dos dados recebidos.

    5. ValidateBusinessContentXsd - Método para validação do BusinessContent a partir do XSD da mensagem.

    6. ValidatedSharedMode - Método para validação do nível de compartilhamento da entidade no sistema integrado com relação ao do RM.

    7. ExecuteReceive - Método responsável pelo processamento da mensagem, a partir dos dados fornecidos no BusinessContent. 

    8. GetReturnContent - Método responsável por retornar ao EAI o ReturnContent a ser devolvido ao sistema que originou a integraçãoProcessResponseMessage - Método responsável por processar os dados retornados pelo aplicativo integrado, como atualizar algum campo de controle ou transformar o dado em caso de consultas, como esta mensagem.

  2. Decorar a classe do adapter com o atributo "AdapterAttr".

    1. O atributo deve receber as informações obrigatórias, como nome da mensagem, versão, descrição e tipo (event/request).

  3. Implementar as classes de modelo referentes ao BusinessContent e ao ReturnContent da Mensagem Padronizada TOTVS, que serão utilizadas na serialização e deserialização das mensagens.

  4. As classes de modelo devem ser decoradas com o atributo "MessageContentTypeAttr" informando os atributos, descritos abaixo.
    1. TransactionName - Nome da transação referente a este modelo.
    2. MajorVersion - Versão cheia da mensagem. 
      1. Exemplo: Versão 1.003 possui MajorVersion 1. 
      2. Exemplo 2: Versão 3.023 possui MajorVersion 3.
    3. MessageType -  Tipo da transação a ter seu conteúdo de negócio serializado/deserializado utilizando esta classe (BusinessMessage ou ResponseMessage).

Código Fonte

Deck of Cards
startHiddenfalse
historyfalse
idCodigoSemClasseBase
Card
defaulttrue
idAdapter
labelAdapter
titleAdapter
Bloco de código
languagec#
firstline1
linenumberstrue
using RM.Eai.TotvsMessage.Intf;
using RM.Eai.TotvsMessage.IService;
using RM.Eai.TotvsMessage.Lib;
using RM.Lib;
using System.Collections.Generic;
using System.Data;

namespace RM.Eai.TotvsMessage.Adapter
{
  [AdapterAttr(typeof(Properties.Resources),nameof(Properties.Resources.sEaiCaptionWhoIs), "WHOIS", "1.000", SubTypeEnum.teRequest)]
  public class WhoIs_SendReceive_1000 : IAdapterSendIAdapterReceive
  {
    #region PropertiesPropriedades
    private EAIAdapterContext AdapterContext { get; set; }
    #endregion 

    /// <summary>
    /// Método de inicialização do Adapter.adapter
    /// </summary>
    /// <param name="adapterContext">Contexto de execução doda Adapter<mensagem</param>
    public void InitializeAdapter(EAIAdapterContext adapterContext)
    {
      AdapterContext = adapterContext;
    }

    /// <summary>
    /// Método responsável por informarprocessar aoos EAI se a mensagem deve ser processada, ignorada ou gerar exceçãodados recebidos.
    /// </summary>
    /// <param name="parms">Parametros<>Parâmetros de entrada</param>
    /// <returns>Retorno<<returns>Resultado do processamento dos dados recebidos</returns>
    public EAICanExecuteSendResultEAIExecReceiveResult CanExecuteExecuteReceive(EAICanExecuteSendParamsEAIExecReceiveParams parms)
    {
      EAIExecReceiveResult result = new EAIExecReceiveResult();
      //NãoEste existeadapter condicional,não sempreexecuta permitindo enviar.
      return new EAICanExecuteSendResult() { CanExecute = EAICanExecuteEnum.csEnviar }processamento, visto seu objetivo de consulta de dados.
      return result;
    }

    /// <summary>
    /// Método responsável por transformarcriar oso parâmetrosReturnContent deque entradaserá noretornado BusinessContentao aaplicativo ser enviadointegrado
    /// </summary>
    /// <param name="parms">Parâmetros originais<de entrada</param>
    /// <returns>Resultado do método de preparação, com o Objeto BusinessContent<ReturnContent</returns>
    public EAIPrepareSendResultEAIGetReturnContentReceiveResult PrepareGetReturnContent(EAIPrepareSendParmsEAIGetReturnContentReceiveParams parms)
    {
      EAIPrepareSendResultEAIGetReturnContentReceiveResult result = new EAIPrepareSendResultEAIGetReturnContentReceiveResult();
      
      //A mensagemServiço de WhoIsconsulta nãode possuirotas
 dados no BusinessContent
   IEAITransacaoAppData dataServer = result.BusinessContent = new WhoIsModel_V1_BusinessContent();

      return result;RMSBroker.CreateServer<IEAITransacaoAppData>("EAITransacaoAppData");

    }

    ///Obtém <summary>
tabela com rotas ativas
 /// Processa ReturnContent recebido, transformando noDataTable objetodtbRotas no formato esperado pelo método chamador.
    /// </summary>
= dataServer.GetAppRoutes(AdapterContext.ContextItem.CurrentRoute.IdApp);

      ///Converte <param name="parms">Parâmetrospro modelo de entrada</param>retorno
    /// <returns>Resultado</returns>
    public EAIProcessResponseMessageSendResult ProcessResponseMessage(EAIProcessResponseMessageSendParams parms) WhoIsModel_V1_ReturnContent returnContentObj = new WhoIsModel_V1_ReturnContent();
    {
  foreach (DataRow rowRota  EAIProcessResponseMessageSendResult result = new EAIProcessResponseMessageSendResult(parms.ResponseMessageItem);

in dtbRotas.Rows)
      //Obtém{
 o ReturnContent deserializado para o tipo definido
      WhoIsModel_V1_ReturnContentEnabledTransaction returnContenttransaction = new (WhoIsModel_V1_ReturnContent)parms.ResponseMessageItem.ResponseMessage.ReturnContent.ReturnContentObjEnabledTransaction();

      //Converte lista detransaction.Name transações no tipo de retorno.= RMSConvert.ToString(rowRota["TRANSACAO"]);
      EAIWhoIsResult  listaTransacoestransaction.Version = new EAIWhoIsResult(AdapterContext.ContextItem.CurrentRoute.IdAppRMSConvert.ToString(rowRota["VERSAO"]);

       //Percorre todas as transações transaction.Mode = ConverteModoHabilitado(RMSConvert.ToString(rowRota["MODOHABILITADO"]));

      foreach (WhoIsModel_V1_EnabledTransaction enabledTransaction in returnContent.EnabledTransactions) returnContentObj.EnabledTransactions.Add(transaction);
      {}

      result.ReturnContent = returnContentObj;

   EAIWhoIsTransaction transacao = new EAIWhoIsTransaction()
  return result;
    }

    private  {string ConverteModoHabilitado(string ModoHabilitado)
    {
      ModoHabilitadoswitch = ConvertModoHabilitado(RMSConvertEnabledMode.ToStringEnum(enabledTransaction.ModeModoHabilitado)),//DONOTLOCALIZE
      {
    NomeMensagem    =case RMSConvert.ToString(enabledTransaction.Name),//DONOTLOCALIZEEnabledModeEnum.emSend:
          Versao = RMSConvert.ToString(enabledTransaction.Version)return "SEND_ENABLED";//DONOTLOCALIZE
        };
case EnabledModeEnum.emReceive:
         listaTransacoes.Add(transacao); return "RECEIVE_ENABLED";//DONOTLOCALIZE
      }

  case EnabledModeEnum.emBoth:
          return "BOTH_ENABLED";//ObtémDONOTLOCALIZE
    o UUID da mensagem originaldefault:
      listaTransacoes.BusinessMessageUUID   = thisRMSException.AdapterContext.ContextItem.Message.UUID;
Throw(string.Format(Properties.Resources.sEaiErroWhoIsModoInvalido, ModoHabilitado));
          //ObtémO método acima gera exceção, mas o compilador UUIDnão dacompreende.
 mensagem de resposta
      listaTransacoes.ResponseMessageUUID = parms.ResponseMessageItem.MessageInformation.UUID;

      //Adiciona no objeto de retorno //A linha abaixo foi inserida para permitir compilação mas nunca será executada.
      result.Data = listaTransacoes    return "";
      }
    }

    //Retorna o dado processado, no tipo de retorno esperado/ <summary>
    /// Método responsável por atualizar o contexto.
    /// </summary>
 return result;
  ///  }

<param name="parms"></param>
    privatepublic EnabledModeEnumvoid ConvertModoHabilitadoChangeRMContext(stringEAIChangeRMContextReceiveParms Modeparms)
    {
      switch (Mode.ToUpperInvariant())
      {//Desnecessária alteração de contexto pois o adapter acessa somente informações globais.
    }

    case "SEND_ENABLED":///DONOTLOCALIZE <summary>
    /// Método para validação do BusinessContent frente return EnabledModeEnum.emSend;ao XSD
    /// </summary>
   case "RECEIVE_ENABLED": ///DONOTLOCALIZE
 <param name="parms">Parâmetros de entrada</param>
    public void return EnabledModeEnum.emReceive;
ValidateBusinessContentXsd(EAIValidateBusinessContextXsdParams parms)
    {
     case "BOTH_ENABLED"://DONOTLOCALIZE
Desnecessária validação pois o adapter não possui propriedades no BusinessContent
 return EnabledModeEnum.emBoth;
  }

      default:/// <summary>
    /// Método de validação do  RMSException.Throw(string.Format(Properties.Resources.sEaiErroWhoIsModoInvalido, Mode));compartilhamento por Empresa/Filial
    /// </summary>
     ///O método acima gera exceção, mas o compilador não compreende. <param name="parms">Parâmetros de entrada</param>
    /// <returns>Resultado da validação</returns>
    public EAIValidatedSharedModeResult ValidatedSharedMode(EAIValidatedSharedModeParams parms)
    //A{
 linha abaixo foi inserida para permitir//Desnecessária compilaçãovalidação maspois nuncaesta serámensagem executada.
não possui compartilhamento por Empresa/Filial
      return 0;//EnabledModeEnum
      }new EAIValidatedSharedModeResult() { Validated = true };
    }
  }
}


Card
idBusinessContentModel
labelBusinessContent Model
titleBusinessContent Model
Bloco de código
languagec#
firstline1
linenumberstrue
using RM.Eai.TotvsMessage.IService;
using RM.Eai.TotvsMessage.Lib;
using System.Collections.Generic;

namespace RM.Eai.TotvsMessage.Adapter
{
  [System.SerializableAttribute()]
  [System.ComponentModel.DesignerCategoryAttribute("code")]
  [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
  [System.Xml.Serialization.XmlRootAttribute(ElementName = "BusinessContent", IsNullable = false)]
  [MessageContentTypeAttr("WHOIS", 1, MessageTypeEnum.tmBusinessMessage)]
  public partial class WhoIsModel_V1_BusinessContent
  {
	//O BusinessContent da mensagem WhoIs não possui propriedades.
  }
}
Card
idReturnContentModel
labelReturnContent Model
titleReturnContent Model
Bloco de código
languagec#
firstline1
linenumberstrue
using RM.Eai.TotvsMessage.IService;
using RM.Eai.TotvsMessage.Lib;
using System.Collections.Generic;

namespace RM.Eai.TotvsMessage.Adapter
{
  [System.SerializableAttribute()]
  [System.ComponentModel.DesignerCategoryAttribute("code")]
  [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
  [System.Xml.Serialization.XmlRootAttribute(ElementName = "ReturnContent", IsNullable = false)]
  [MessageContentTypeAttr("WHOIS", 1, MessageTypeEnum.tmResponseMessage)]
  public partial class WhoIsModel_V1_ReturnContent
  {
    [System.Xml.Serialization.XmlArrayItemAttribute("Transaction", IsNullable = false)]
    public List<WhoIsModel_V1_EnabledTransaction> EnabledTransactions { get; set; } = new List<WhoIsModel_V1_EnabledTransaction>();
  }

  /// <remarks/>
  [System.SerializableAttribute()]
  [System.ComponentModel.DesignerCategoryAttribute("code")]
  [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
  public partial class WhoIsModel_V1_EnabledTransaction
  {
    public string Mode { get; set; }
    public string Version { get; set; }
    public string Name { get; set; }
  }
}

Implementações de produto

Os times dos segmentos tiveram iniciativa de desenvolver classes base e auxiliares para executar ações comuns e assim aumentar a produtividade no desenvolvimento de adapters. Estas classes estão disponíveis no projeto "RM.EAI.TotvsMessage.Adapter", que mesmo estando na solution do EAI é de domínio e manutenção dos times de produto.

A forma de uso destas classes foi documentada pelo produto no link a seguir: Desenvolvimento - AdapterEAI 2.

04. Assuntos Relacionados