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 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 |
---|
|
draw.io Diagram |
---|
border | true |
---|
viewerToolbar | true |
---|
| |
---|
fitWindow | false |
---|
diagramName | AdapterReceive |
---|
simpleViewer | false |
---|
width | |
---|
diagramWidth | 686 |
---|
revision | 3 |
---|
|
Fluxo de mensagem de consulta
O diagrama abaixo apresenta um possível fluxo de processamento de uma mensagem síncrona recebida, exemplificando com chamada a um Module, mas também se aplica ao consumo de DataServers, Subscribers ou qualquer outro objeto de negócio.
Principais funções do adapter de recebimento
- Gerar o conteúdo de negócio da mensagem a enviar (BusinessContent).
- 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.
- 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.
- 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 recebimento
Para que uma classe seja um adapter de envio, deve-se atender aos pré-requisitos listados abaixo e realizar as funções de integração listadas anteriormente.
Pré-requisitos
Implementar a interface IAdapterSend, 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 - 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.
ProcessResponseMessage - 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;
using RM.Lib;
using System.Data;
namespace RM.Eai.TotvsMessage.Adapter
{
[AdapterAttr(typeof(Properties.Resources),nameof(Properties.Resources.sEaiCaptionWhoIs), "WHOIS", "1.000", SubTypeEnum.teRequest)]
public class WhoIs_Receive_1000_WithoutBase : IAdapterReceive
{
#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;
}
/// <summary>
/// Método responsável por processar os dados recebidos.
/// </summary>
/// <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();
//Este adapter não executa processamento, visto seu objetivo de consulta de dados.
return result;
}
/// <summary>
/// Método responsável por criar o ReturnContent que será retornado ao aplicativo integrado
/// </summary>
/// <param name="parms">Parâmetros de entrada</param>
/// <returns>Resultado com o ReturnContent</returns>
public EAIGetReturnContentReceiveResult GetReturnContent(EAIGetReturnContentReceiveParams parms)
{
EAIGetReturnContentReceiveResult result = new EAIGetReturnContentReceiveResult();
//Serviço de consulta de rotas
IEAITransacaoAppData dataServer = RMSBroker.CreateServer<IEAITransacaoAppData>("EAITransacaoAppData");
//Obtém tabela com rotas ativas
DataTable dtbRotas = dataServer.GetAppRoutes(AdapterContext.ContextItem.CurrentRoute.IdApp);
//Converte pro modelo de retorno
WhoIsModel_V1_ReturnContent returnContentObj = new WhoIsModel_V1_ReturnContent();
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 ConverteModoHabilitado(string ModoHabilitado)
{
switch (EnabledMode.Enum(ModoHabilitado))
{
case EnabledModeEnum.emSend:
return "SEND_ENABLED";//DONOTLOCALIZE
case EnabledModeEnum.emReceive:
return "RECEIVE_ENABLED";//DONOTLOCALIZE
case EnabledModeEnum.emBoth:
return "BOTH_ENABLED";//DONOTLOCALIZE
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 "";
}
}
/// <summary>
/// Método responsável por atualizar o contexto.
/// </summary>
/// <param name="parms"></param>
public void ChangeRMContext(EAIChangeRMContextReceiveParms parms)
{
//Desnecessária alteração de contexto pois o adapter acessa somente informações globais.
}
/// <summary>
/// Método para validação do BusinessContent frente ao XSD
/// </summary>
/// <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
}
/// <summary>
/// Método de validação do compartilhamento por Empresa/Filial
/// </summary>
/// <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 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 - Adapter.
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.