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 |
|---|
| border | true |
|---|
| viewerToolbar | true |
|---|
| fitWindow | false |
|---|
| diagramName | AdapterReceive |
|---|
| simpleViewer | false |
|---|
| diagramWidth | 686 |
|---|
| revision | 3 |
|---|
|
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 |
|---|
| border | true |
|---|
| viewerToolbar | true |
|---|
| |
|---|
| fitWindow | false |
|---|
| diagramName | AdapterReceiveConsulta |
|---|
| simpleViewer | false |
|---|
| width | |
|---|
| diagramWidth |
|---|
|
608
1
Principais funções do adapter de recebimento
- 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).
- 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.
- 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.
- interpretar os dados recebidos e transformar no modelo esperado pela interface do Server que será consumido.
- 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.
- Interpretar o processamento e gerar o objeto com as informações Transformar e/ou processar as informações de negócio da resposta (ReturnContent).
- 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.
- Ex.: Mensagens de consulta de informações devem transformar o dado recebido antes de encaminhar para o módulo de consulta.
- É responsabilidade do adapter gerar o ReturnContent que será retornado ao aplicativo integrado.
- 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.
- 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.- Ex.: Mensagens de cadastro devem ter o De-Para armazenado na base de dados.
- Ex2.: Mensagens assíncronas que devam desbloquear o registro no momento do retorno de sucesso.
03. Implementação de um adapter de
enviorecebimento
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
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".
InitializeAdapter - Método responsável pela inicialização do Adapter, recebendo o contexto de execução por referência.
CanExecute ChangeRMContext - Método que permite ao adapter realizar verificações e informar se a mensagem deve ser processada, ignorada ou gerar exceção.
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.
deve ser utilizado para compor o RMSContext a partir dos dados recebidos.
ValidateBusinessContentXsd - Método para validação do BusinessContent a partir do XSD da mensagem.
ValidatedSharedMode - Método para validação do nível de compartilhamento da entidade no sistema integrado com relação ao do RM.
ExecuteReceive - Método responsável pelo processamento da mensagem, a partir dos dados fornecidos no BusinessContent.
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.
Decorar a classe do adapter com o atributo "AdapterAttr".
O atributo deve receber as informações obrigatórias, como nome da mensagem, versão, descrição e tipo (event/request).
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.
- As classes de modelo devem ser decoradas com o atributo "MessageContentTypeAttr" informando os atributos, descritos abaixo.
- TransactionName - Nome da transação referente a este modelo.
- MajorVersion - Versão cheia da mensagem.
- Exemplo: Versão 1.003 possui MajorVersion 1.
- Exemplo 2: Versão 3.023 possui MajorVersion 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 |
|---|
| startHidden | false |
|---|
| history | false |
|---|
| id | CodigoSemClasseBase |
|---|
|
| Card |
|---|
| default | true |
|---|
| id | Adapter |
|---|
| label | Adapter |
|---|
| title | Adapter |
|---|
| | Bloco de código |
|---|
| language | c# |
|---|
| firstline | 1 |
|---|
| linenumbers | true |
|---|
| using RM.Eai.TotvsMessage.Intf; |
using RM.Eai.TotvsMessage.IService; |
using RM.Eai.TotvsMessage.Lib; |
namespace RM.Eai.TotvsMessage.Adapter |
[AdapterAttr(typeof(Properties.Resources),nameof(Properties.Resources.sEaiCaptionWhoIs), "WHOIS", "1.000", SubTypeEnum.teRequest)] |
public class WhoIs_Receive_1000 | _WithoutBase { #region Propriedades EAIAdapterContext AdapterContext { get; set; } #endregion /// <summary> /// Método de inicialização do adapter /// </summary> /// <param
{
#region Propriedades
EAIAdapterContext AdapterContext { get; set; }
#endregion
/// <summary>
/// Método de inicialização do adapter
/// </summary>
/// <param name="adapterContext">Contexto de execução da mensagem</param> |
public void InitializeAdapter(EAIAdapterContext adapterContext) |
{ AdapterContext = adapterContext; }
{
AdapterContext = adapterContext;
}
/// <summary> |
/// Método responsável por processar os dados recebidos. |
/// <param name="parms">Parâmetros de entrada</param> |
/// <returns>Resultado do processamento dos dados recebidos</returns> |
public EAIExecReceiveResult ExecuteReceive(EAIExecReceiveParams parms) |
{ EAIExecReceiveResult result = new
{
EAIExecReceiveResult result = new EAIExecReceiveResult(); |
//Este adapter não executa processamento, visto seu objetivo de consulta de dados. |
return result; }
return result;
}
/// <summary> |
/// Método responsável por criar o ReturnContent que será retornado ao aplicativo integrado |
/// <param name="parms">Parâmetros de entrada</param> |
/// <returns>Resultado com o ReturnContent</returns> |
public EAIGetReturnContentReceiveResult GetReturnContent(EAIGetReturnContentReceiveParams parms) |
{ EAIGetReturnContentReceiveResult result = new
{
EAIGetReturnContentReceiveResult result = new EAIGetReturnContentReceiveResult(); |
rotas IEAITransacaoAppData dataServer = rotas
IEAITransacaoAppData dataServer = RMSBroker.CreateServer<IEAITransacaoAppData>("EAITransacaoAppData"); |
ativas DataTable dtbRotas = ativas
DataTable dtbRotas = dataServer.GetAppRoutes(AdapterContext.ContextItem.CurrentRoute.IdApp); |
retorno
retorno
WhoIsModel_V1_ReturnContent returnContentObj = new WhoIsModel_V1_ReturnContent(); |
foreach
foreach (DataRow rowRota in dtbRotas.Rows) |
{
{
WhoIsModel_V1_EnabledTransaction transaction = new WhoIsModel_V1_EnabledTransaction(); |
transaction.Name = RMSConvert.ToString(rowRota["TRANSACAO"]); |
transaction.Version = RMSConvert.ToString(rowRota["VERSAO"]); |
transaction.Mode = ConverteModoHabilitado(RMSConvert.ToString(rowRota["MODOHABILITADO"])); |
returnContentObj.EnabledTransactions.Add(transaction); |
}
}
result.ReturnContent = returnContentObj; |
return result; } private string
return result;
}
private string ConverteModoHabilitado(string ModoHabilitado) |
{ switch
{
switch (EnabledMode.Enum(ModoHabilitado)) |
{ case
{
case EnabledModeEnum.emSend: |
return
return "SEND_ENABLED";//DONOTLOCALIZE |
case
case EnabledModeEnum.emReceive: |
return
return "RECEIVE_ENABLED";//DONOTLOCALIZE |
case
case EnabledModeEnum.emBoth: |
return
return "BOTH_ENABLED";//DONOTLOCALIZE |
default:
default:
RMSException.Throw(string.Format(Properties.Resources.sEaiErroWhoIsModoInvalido, ModoHabilitado)); |
//O método acima gera exceção, mas o compilador não compreende. |
//A linha abaixo foi inserida para permitir compilação mas nunca será executada. |
return } }
/// Método responsável por atualizar o contexto. |
/// <param name="parms"></param> |
public void ChangeRMContext(EAIChangeRMContextReceiveParms parms) |
{
{
//Desnecessária alteração de contexto pois o adapter acessa somente informações globais. |
}
/// Método para validação do BusinessContent frente ao XSD |
/// <param name="parms">Parâmetros de entrada</param> |
public void ValidateBusinessContentXsd(EAIValidateBusinessContextXsdParams parms) |
{
{
//Desnecessária validação pois o adapter não possui propriedades no BusinessContent |
}
/// Método de validação do compartilhamento por Empresa/Filial |
/// <param name="parms">Parâmetros de entrada</param> |
/// <returns>Resultado da validação</returns> |
public EAIValidatedSharedModeResult ValidatedSharedMode(EAIValidatedSharedModeParams parms) |
{
{
//Desnecessária validação pois esta mensagem não possui compartilhamento por Empresa/Filial |
return new
return new EAIValidatedSharedModeResult() { Validated = true }; |
} } } |
| Card |
|---|
| id | BusinessContentModel |
|---|
| label | BusinessContent Model |
|---|
| title | BusinessContent Model |
|---|
| | Bloco de código |
|---|
| language | c# |
|---|
| firstline | 1 |
|---|
| linenumbers | true |
|---|
| 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 |
|---|
| id | ReturnContentModel |
|---|
| label | ReturnContent Model |
|---|
| title | ReturnContent Model |
|---|
| | Bloco de código |
|---|
| language | c# |
|---|
| firstline | 1 |
|---|
| linenumbers | true |
|---|
| 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
- Entidades Relacionadas ao EAI 2.0
- Documento técnico da criação do Conversor para EAI 2.0
- Desenvolvimento de Adapters com as classes base dos segmentos.