Histórico da Página
Índice | ||
---|---|---|
|
01. Apresentação
Este documento técnico tem por objetivo auxiliar os desenvolvedores dos segmentos na criação de classes que "publicam" e/ou "consomem" mensagens através da plataforma Totvs SmartLink.
02. Responsabilidades
O desenvolvimento e manutenção dos publicadores e consumidores de mensagens são de responsabilidade das equipes de segmentos. Os artefatos genéricos que controlam a fila de execução das mensagens são de responsabilidade da equipe de Framework.
03. Implementando um publicador de mensagens
Para que uma classe seja um publicador de mensagens, deve-se atender aos pré-requisitos listados abaixo:
Pré-requisitos
- Criar um projeto (classLibrary .NET) na solution do segmento em questão, com o seguinte padrão de nome: RM.[Segmento].XXX.SmartLink.Service.
- Exemplo: RM.Glb.SGDP.SmartLink.Service.dll
- Adicionar referência para a dll "RM.Lib.SmartLink.dll";
Criar uma classe que receba em seu construtor instâncias das seguintes interfaces:
"IRMSSmartLinkPublisherService": interface de serviço responsável em incluir a mensagem na fila do RM.SmartLink.Client.
Foi criada na Lib uma classe de "Factory" responsável em fornecer uma instância para interface "IRMSSmartLinkPublisherService". Trata-se da classe "RMSSmartLinkPublisherFactory"Informações .
Basta chamar seu método público "NewSmartLinkPublisher" para obter uma instância contendo essa responsabilidade."IRMSLogger": serviço usado para incluir logs relacionados à regra de negócio em questão.
Informações Todos os logs adicionados nesse serviço serão gravados automaticamente na tabela "GTotvsLinkLog"
Para publicar uma mensagem na fila do RM.SmartLink.Client, basta chamar o método "AddMessage" da instância de interface "IRMSSmartLinkPublisherService". Os seguinte dados devem ser enviados através de uma classe de parâmetros do tipo "SmartLinkPublisherAddMessageParams":
Propriedade Descrição Command Nome do comando a ser incluído na fila do SmartLink. Ex: SGDPUpdateTenantMetada CorrelatedId Pode ser ser enviado nessa propriedade um identificador (guid) que correlacionam mensagens de envio e resposta. Data Dados da mensagem contendo informações relacionadas ao negócio. Pode ser em qualquer formato (json, xml, etc) desde que o consumidor consiga interpretá-lo.
RouterMessage Rota de envio da mensagem. Será concatenada ao endpoint do serviço do Totvs SmartLink.Server. ex: /api/v1/link/send/SGDPMaskResponse/SGDP
- Diagrama de classes contendo um publicador de mensagem de exemplo:
5. Diagrama de sequência contendo um exemplo do ciclo de vida da inclusão da mensagem "SGDPTenantMetada"
5. Código fonte de exemplo (extraído da classe "GlbSGDPPublisherMessageService" localizada na solution de Globais, projeto "RM.Glb.SGDP.SmartLink.Service"
...
language | c# |
---|---|
firstline | 1 |
linenumbers | true |
...
Na versão 12.1.2402, que utiliza api REST para envio de mensagem, o valor do Audience é definido no final do RouterMessage. No caso desse exemplo o Audience é o SGDP.
A partir da versão 12.1.2406 não é necessário passar o RouterMessage como parâmetro pois utiliza o protocolo gRPC para envio de mensagem.Audience Código do TOTVS App específico que irá receber a mensagem.
Para versões 12.1.2406 e acima, que já utiliza o gRPC para envio de mensagem, o Audience deve ser passado por esse parâmetro.
- Diagrama de classes contendo um publicador de mensagem de exemplo:
5. Diagrama de sequência contendo um exemplo do ciclo de vida da inclusão da mensagem "SGDPTenantMetada"
6. Código fonte de exemplo (extraído da classe "GlbSGDPPublisherMessageService" localizada na solution de Globais, projeto "RM.Glb.SGDP.SmartLink.Service". Esse exemplo é para versões a partir da 12.1.2406 que já utiliza o protocolo gRPC.
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
using RM.Glb.SGDP.SmartLink.Service.Domain.Domain.Interfaces; using RM.Lib.Data; using RM.Lib.Log; using RM.LibGlb.SGDP.SmartLink.Service.Domain.DataModel.Interfaces; using RM.Lib.Log; using RM.Lib.SmartLink.Domain.Interfaces; using RM.Lib.SmartLink.Domain.PublisherInterfaces; using System; using System.Collections.Generic; using System.Linq; namespace RM.Glb.SGDP.SmartLink.Service { public class GlbSGDPPublisherMessageService : IGlbSGDPPublisherMessageService { private IGlbSGDPResolverService _SGDPResolverService/// <summary> /// SGDP Publisher Message Service class /// </summary> public class GlbSGDPPublisherMessageService : IGlbSGDPPublisherMessageService { private readonly IGlbSGDPResolverService _sgdpResolverService; private readonly IRMSSmartLinkPublisherService _SmartLinkPublisherServicesmartLinkPublisherService; private readonly IRMSLogger _LogServicelogService; private const string ctSGDPMaskResponseEndPointctSGDPAudience = "/api/v1/link/send/SGDPMaskResponse/SGDP"; private const string ctSGDPDataResponseEndPoint = "/api/v1/link/send/SGDPDataResponse/SGDP"; private const string ctSGDPUpdateTenantMetadataEndPoint = "/api/v1/link/send/SGDPUpdateTenantMetadata/SGDP"; // <-- SEU CÓDIGO DE AUDIENCE DEVE VIR AQUI. NO CASO DESSE EXEMPLO É SGDP. OBTER O CÓDIGO COM A EQUIPE DE TOTVS APPS. private const string ctSGDPUpdateTenantMetadata = "SGDPUpdateTenantMetadata"; private const string ctSGDPDataCommand = "SGDPDataCommand"; private const string ctSGDPMaskCommandctSGDPResponseDataCommand = "SGDPMaskCommandSGDPDataResponse"; private const string ctSGDPResponseDataCommandctSGDPMaskCommand = "SGDPResponseDataCommandSGDPMaskCommand"; private const string ctSGDPResponseMaskCommand = "SGDPResponseMaskCommandSGDPMaskResponse"; private const string ctSmartLinkSetupCommandctSGDPLogsCommand = "SetupSGDPLogsCommand"; private const string ctSmartLinkUnSetupCommandctSGDPResponseLogCommand = "UnSetupSGDPLogsResponse"; public GlbSGDPPublisherMessageService(IRMSSmartLinkPublisherService smartLinkPublisherService, private const string ctSmartLinkSetupCommand = "setup"; private const string IGlbSGDPResolverServicectSmartLinkUnSetupCommand sgdpResolverService, = "unSetup"; /// IRMSLogger logService)<summary> /// Constructor {/// </summary> /// <param _SmartLinkPublisherService name= smartLinkPublisherService;"smartLinkPublisherService"></param> /// <param _SGDPResolverService name= sgdpResolverService;"sgdpResolverService"></param> /// <param _LogService name= logService;"logService"></param> public GlbSGDPPublisherMessageService(IRMSSmartLinkPublisherService }smartLinkPublisherService, /// <summary>IGlbSGDPResolverService sgdpResolverService, /// AdicionaIRMSLogger umalogService) mensagem de reposta para{ o comando "SGDPResponseDataCommand". _smartLinkPublisherService /// </summary> = smartLinkPublisherService; /// <param_sgdpResolverService name="parms"></param>= sgdpResolverService; public void AddResponseDataCommand(AddResponseDataCommandParms parms)_logService = logService; {} /// <summary> SmartLinkPublisherAddMessageParams parPublisher = new SmartLinkPublisherAddMessageParams(); parPublisher.Command = ctSGDPResponseDataCommand;/// Adiciona uma mensagem de reposta para o comando "SGDPResponseDataCommand". /// parPublisher.CorrelatedId = parms.CorrelatedId; ;</summary> /// <param name="parms"></param> public parPublisher.Data = parms.Message;void AddResponseDataCommand(AddResponseDataCommandParms parms) { parPublisher.RouterMessage = ctSGDPDataResponseEndPoint; SmartLinkPublisherAddMessageParams parPublisher = _LogService.NotifyLogInfo(Properties.Resources.sconTotvsAppSGDPResponseDataCommandGravadoNaFila);new SmartLinkPublisherAddMessageParams _SmartLinkPublisherService.AddMessage(parPublisher);{ } /// <summary>Command = ctSGDPResponseDataCommand, /// Adiciona uma mensagem deCorrelatedId reposta para o comando "SGDPResponseMaskCommand".= parms.CorrelatedId, /// </summary> Data /// <param name="parms"></param>= parms.Message, public void AddResponseMaskCommand(AddResponseMaskCommandParms parms) { Audience = ctSGDPAudience }; SmartLinkPublisherAddMessageParams parPublisher = new SmartLinkPublisherAddMessageParams( _logService.NotifyLogInfo(Properties.Resources.sconTotvsAppSGDPResponseDataCommandGravadoNaFila); parPublisher.Command = ctSGDPResponseMaskCommand_smartLinkPublisherService.AddMessage(parPublisher); } parPublisher.CorrelatedId = parms.CorrelatedId; /// <summary> /// Adiciona parPublisher.Datauma = parms.Message; parPublisher.RouterMessage = ctSGDPMaskResponseEndPoint; _LogService.NotifyLogInfo(Properties.Resources.sconTotvsAppSGDPResponseMaskCommandGravadoNaFila);mensagem de reposta para o comando "SGDPResponseMaskCommand". /// </summary> /// <param name="parms"></param> public void _SmartLinkPublisherService.AddMessage(parPublisher);AddResponseMaskCommand(AddResponseMaskCommandParms parms) }{ /// <summary> SmartLinkPublisherAddMessageParams parPublisher = new ///SmartLinkPublisherAddMessageParams Adiciona uma mensagem para envio de{ um comando de sgldpdateapplicationmetada. /// </summary>Command = ctSGDPResponseMaskCommand, public void AddMessageUpdateTenantMetadata(AddMessageUpdateTenantMetadataParms parms) CorrelatedId {= parms.CorrelatedId, if (CanAddTenantMetadataMessage()) Data = parms.Message, { Audience = tryctSGDPAudience {}; _logService.NotifyLogInfo(Properties.Resources.sconTotvsAppSGDPResponseMaskCommandGravadoNaFila); List<string> jsons = GetUpdateTenandMetadata(parms.TenantId _smartLinkPublisherService.AddMessage(parPublisher); } /// <summary> foreach (string json in jsons) { /// Adiciona uma mensagem de reposta para o comando "SGDPResponseLogCommand". /// </summary> /// <param name="parms">Parms</param> SmartLinkPublisherAddMessageParams smartLinkParmspublic =void new SmartLinkPublisherAddMessageParams();AddResponseLogCommand(AddResponseLogCommandParms parms) { SmartLinkPublisherAddMessageParams parPublisher smartLinkParms.Command = ctSGDPUpdateTenantMetadata; new SmartLinkPublisherAddMessageParams { smartLinkParms.CorrelatedIdCommand = ""; ctSGDPResponseLogCommand, CorrelatedId = parms.CorrelatedId, smartLinkParms.Data = json; Data = parms.Message, smartLinkParms.RouterMessageAudience = ctSGDPUpdateTenantMetadataEndPoint;ctSGDPAudience }; _LogServicelogService.NotifyLogInfo(Properties.Resources.sconTotvsAppSGDPTenantMetadaGravadoNaFilasconTotvsAppSGDPResponseLogCommandGravadoNaFila); _SmartLinkPublisherServicesmartLinkPublisherService.AddMessage(smartLinkParmsparPublisher); } /// }<summary> /// Adiciona uma mensagem } para envio de um comando de sgldpdateapplicationmetada. catch (Exception ex) /// </summary> /// {<param name="parms"></param> public void AddMessageUpdateTenantMetadata(AddMessageUpdateTenantMetadataParms parms) _LogService.NotifyLogWarning(ex, Properties.Resources.sconTotvsAppErroAoEnviarSGDPUpdateTenantMetadata); { }try }{ } private bool CanAddTenantMetadataMessage()if (string.IsNullOrEmpty(parms.TenantId)) { //Se existir alguma mensagem de sgdp para ser processada, então não envia atualizaçaõ de medatdos pois esse processo é caro. _logService.NotifyLogWarning(Properties.Resources.sSGDPTenantMetadataInvalidSGDPUpdateTenantMetadata); return; } var List<string> pendingMessagesjsons = _SmartLinkPublisherService.GetPendingMessages(GetUpdateTenandMetadata(parms.TenantId); List<SmartLinkMessageDataModel> messageUpstream = pendingMessages?.Messages?.Where( foreach (string json in jsons) { y => y.TypeEvent == ctSGDPUpdateTenantMetadata || SmartLinkPublisherAddMessageParams smartLinkParms = new SmartLinkPublisherAddMessageParams y.TypeEvent == ctSGDPDataCommand ||{ Command y.TypeEvent == ctSGDPMaskCommand || ctSGDPUpdateTenantMetadata, y.TypeEventCorrelatedId == ctSGDPResponseDataCommand || "", Data y.TypeEvent == ctSGDPResponseMaskCommand).ToList();= json, if (messageUpstream?.Count > 0)//Se existir alguma nãoAudience inclua= na fila... ctSGDPAudience return false}; return true _logService.NotifyLogInfo(Properties.Resources.sconTotvsAppSGDPTenantMetadaGravadoNaFila); } private List<string> GetUpdateTenandMetadata(string tenantId)_smartLinkPublisherService.AddMessage(smartLinkParms); { } return _SGDPResolverService.GetSGDPTenantMetadata( } new catch MetadataTenantParms(Exception ex) { TenantId = tenantId }{ )?.JsonsResult; _logService.NotifyLogWarning(ex, Properties.Resources.sconTotvsAppErroAoEnviarSGDPUpdateTenantMetadata); } } publicprivate voidList<string> AddMessageUnSetupGetUpdateTenandMetadata(string tenantId) { var pendingMessages =return _SmartLinkPublisherServicesgdpResolverService.GetPendingMessagesGetSGDPTenantMetadata(); List<SmartLinkMessageDataModel> messagesSGDP =new MetadataTenantParms() { TenantId = tenantId } pendingMessages?.Messages?.Where(y => y.TypeEvent.ToUpper() == ctSGDPUpdateTenantMetadata.ToUpper() &&)?.JsonsResult; } /// <summary> /// Adiciona mensagem UnSetup /// </summary> public void AddMessageUnSetup() { var pendingMessages = _smartLinkPublisherService.GetPendingMessages(); var messagesSGDP = pendingMessages?.Where(y => y.TypeEvent.ToUpper() == ctSGDPDataCommandctSGDPUpdateTenantMetadata.ToUpper() && y.TypeEvent.ToUpper() == ctSGDPMaskCommandctSGDPDataCommand.ToUpper() && y.TypeEvent.ToUpper() == ctSGDPResponseDataCommandctSGDPMaskCommand.ToUpper() && y.TypeEvent.ToUpper() == ctSGDPResponseMaskCommandctSGDPLogsCommand.ToUpper()).ToList(); && foreach (SmartLinkMessageDataModel model in messagesSGDP) _SmartLinkPublisherService.RemoveMessageById(model.Id); SmartLinkPublisherAddMessageParams parms = new SmartLinkPublisherAddMessageParams(); parms.Command = ctSmartLinkUnSetupCommand; parms.CorrelatedId = ""; parms.Datay.TypeEvent.ToUpper() == _SGDPResolverServicectSGDPResponseDataCommand.GetSGDPSetupToUpper().JsonResult; && _LogService.NotifyLogInfo(Properties.Resources.sconTotvsAppUnSetupGravadoNaFila); _SmartLinkPublisherService.AddMessage(parms); } public void AddMessageSetup() { SmartLinkPublisherAddMessageParams parms = new SmartLinkPublisherAddMessageParams(); parms.Command = ctSmartLinkSetupCommand; parms.CorrelatedId = ""; y.TypeEvent.ToUpper() == ctSGDPResponseMaskCommand.ToUpper()).ToList(); parms.Data = _SGDPResolverService.GetSGDPSetup().JsonResult;if (messagesSGDP != null) _LogService.NotifyLogInfo(Properties.Resources.sconTotvsAppSetupGravadoNaFila);{ _SmartLinkPublisherService.AddMessage(parms); foreach (SmartLinkMessageEntity model in messagesSGDP) { _smartLinkPublisherService.RemoveMessageById(model.Id); } } } |
04. Implementando um consumidor de mensagens
Para que uma classe seja um consumidor de mensagens no SmartLink, deve-se atender aos pré-requisitos listados abaixo:
Pré-requisitos
SmartLinkPublisherAddMessageParams parms = new SmartLinkPublisherAddMessageParams
{
Command = ctSmartLinkUnSetupCommand,
CorrelatedId = "",
Audience = ctSGDPAudience,
Data = _sgdpResolverService.GetSGDPSetup().JsonResult
};
_logService.NotifyLogInfo(Properties.Resources.sconTotvsAppUnSetupGravadoNaFila);
_smartLinkPublisherService.AddMessage(parms);
}
/// <summary>
/// Adiciona messagem setup
/// </summary>
public void AddMessageSetup()
{
SmartLinkPublisherAddMessageParams parms = new SmartLinkPublisherAddMessageParams
{
Command = ctSmartLinkSetupCommand,
CorrelatedId = "",
Audience = ctSGDPAudience,
Data = _sgdpResolverService.GetSGDPSetup().JsonResult
};
_logService.NotifyLogInfo(Properties.Resources.sconTotvsAppSetupGravadoNaFila);
_smartLinkPublisherService.AddMessage(parms);
}
}
} |
7. Código fonte de exemplo (extraído da classe "GlbSGDPPublisherMessageService" localizada na solution de Globais, projeto "RM.Glb.SGDP.SmartLink.Service". Esse exemplo é para a versão 12.1.2402 que ainda utiliza api REST para envio de mensagem. Nesse caso o Audience é definido no final do endpoint passado como parâmetro para o RouterMessage.
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
using RM.Glb.SGDP.SmartLink.Service.Domain;
using RM.Glb.SGDP.SmartLink.Service.Domain.Interfaces;
using RM.Lib.Log;
using RM.Lib.SmartLink.Domain;
using RM.Lib.SmartLink.Domain.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
namespace RM.Glb.SGDP.SmartLink.Service
{
public class GlbSGDPPublisherMessageService : IGlbSGDPPublisherMessageService
{
private readonly IGlbSGDPResolverService _sgdpResolverService;
private readonly IRMSSmartLinkPublisherService _smartLinkPublisherService;
private readonly IRMSLogger _logService;
private const string ctSGDPUpdateTenantMetadataEndPoint = "/api/v1/link/send/SGDPUpdateTenantMetadata/SGDP";
private const string ctSGDPDataResponseEndPoint = "/api/v1/link/send/SGDPDataResponse/SGDP";
private const string ctSGDPUpdateTenantMetadata = "SGDPUpdateTenantMetadata";
private const string ctSGDPDataCommand = "SGDPDataCommand";
private const string ctSGDPResponseDataCommand = "SGDPDataResponse";
private const string ctSGDPMaskResponseEndPoint = "/api/v1/link/send/SGDPMaskResponse/SGDP";
private const string ctSGDPMaskCommand = "SGDPMaskCommand";
private const string ctSGDPResponseMaskCommand = "SGDPMaskResponse";
private const string ctSGDPLogResponseEndPoint = "/api/v1/link/send/SGDPLogsResponse/SGDP";
private const string ctSGDPLogsCommand = "SGDPLogsCommand";
private const string ctSGDPResponseLogCommand = "SGDPLogsResponse";
private const string ctSmartLinkSetupCommand = "setup";
private const string ctSmartLinkUnSetupCommand = "unSetup";
public GlbSGDPPublisherMessageService(IRMSSmartLinkPublisherService smartLinkPublisherService,
IGlbSGDPResolverService sgdpResolverService,
IRMSLogger logService)
{
_smartLinkPublisherService = smartLinkPublisherService;
_sgdpResolverService = sgdpResolverService;
_logService = logService;
}
/// <summary>
/// Adiciona uma mensagem de reposta para o comando "SGDPResponseDataCommand".
/// </summary>
/// <param name="parms"></param>
public void AddResponseDataCommand(AddResponseDataCommandParms parms)
{
SmartLinkPublisherAddMessageParams parPublisher = new SmartLinkPublisherAddMessageParams
{
Command = ctSGDPResponseDataCommand,
CorrelatedId = parms.CorrelatedId,
Data = parms.Message,
RouterMessage = ctSGDPDataResponseEndPoint
};
_logService.NotifyLogInfo(Properties.Resources.sconTotvsAppSGDPResponseDataCommandGravadoNaFila);
_smartLinkPublisherService.AddMessage(parPublisher);
}
/// <summary>
/// Adiciona uma mensagem de reposta para o comando "SGDPResponseMaskCommand".
/// </summary>
/// <param name="parms"></param>
public void AddResponseMaskCommand(AddResponseMaskCommandParms parms)
{
SmartLinkPublisherAddMessageParams parPublisher = new SmartLinkPublisherAddMessageParams
{
Command = ctSGDPResponseMaskCommand,
CorrelatedId = parms.CorrelatedId,
Data = parms.Message,
RouterMessage = ctSGDPMaskResponseEndPoint
};
_logService.NotifyLogInfo(Properties.Resources.sconTotvsAppSGDPResponseMaskCommandGravadoNaFila);
_smartLinkPublisherService.AddMessage(parPublisher);
}
/// <summary>
/// Adiciona uma mensagem de reposta para o comando "SGDPResponseLogCommand".
/// </summary>
/// <param name="parms">Parms</param>
public void AddResponseLogCommand(AddResponseLogCommandParms parms)
{
SmartLinkPublisherAddMessageParams parPublisher = new SmartLinkPublisherAddMessageParams
{
Command = ctSGDPResponseLogCommand,
CorrelatedId = parms.CorrelatedId,
Data = parms.Message,
RouterMessage = ctSGDPLogResponseEndPoint
};
_logService.NotifyLogInfo(Properties.Resources.sconTotvsAppSGDPResponseLogCommandGravadoNaFila);
_smartLinkPublisherService.AddMessage(parPublisher);
}
/// <summary>
/// Adiciona uma mensagem para envio de um comando de sgldpdateapplicationmetada.
/// </summary>
public void AddMessageUpdateTenantMetadata(AddMessageUpdateTenantMetadataParms parms)
{
try
{
if(string.IsNullOrEmpty(parms.TenantId))
{
_logService.NotifyLogWarning(Properties.Resources.sSGDPTenantMetadataInvalidSGDPUpdateTenantMetadata);
return;
}
List<string> jsons = GetUpdateTenandMetadata(parms.TenantId);
foreach (string json in jsons)
{
SmartLinkPublisherAddMessageParams smartLinkParms = new SmartLinkPublisherAddMessageParams
{
Command = ctSGDPUpdateTenantMetadata,
CorrelatedId = "",
Data = json,
RouterMessage = ctSGDPUpdateTenantMetadataEndPoint
};
_logService.NotifyLogInfo(Properties.Resources.sconTotvsAppSGDPTenantMetadaGravadoNaFila);
_smartLinkPublisherService.AddMessage(smartLinkParms);
}
}
catch (Exception ex)
{
_logService.NotifyLogWarning(ex, Properties.Resources.sconTotvsAppErroAoEnviarSGDPUpdateTenantMetadata);
}
}
private List<string> GetUpdateTenandMetadata(string tenantId)
{
return _sgdpResolverService.GetSGDPTenantMetadata(
new MetadataTenantParms() { TenantId = tenantId }
)?.JsonsResult;
}
public void AddMessageUnSetup()
{
var pendingMessages = _smartLinkPublisherService.GetPendingMessages();
var messagesSGDP =
pendingMessages?.Where(y => y.TypeEvent.ToUpper() == ctSGDPUpdateTenantMetadata.ToUpper() &&
y.TypeEvent.ToUpper() == ctSGDPDataCommand.ToUpper() &&
y.TypeEvent.ToUpper() == ctSGDPMaskCommand.ToUpper() &&
y.TypeEvent.ToUpper() == ctSGDPLogsCommand.ToUpper() &&
y.TypeEvent.ToUpper() == ctSGDPResponseDataCommand.ToUpper() &&
y.TypeEvent.ToUpper() == ctSGDPResponseMaskCommand.ToUpper()).ToList();
if (messagesSGDP != null)
{
foreach (SmartLinkMessageEntity model in messagesSGDP)
{
_smartLinkPublisherService.RemoveMessageById(model.Id);
}
}
SmartLinkPublisherAddMessageParams parms = new SmartLinkPublisherAddMessageParams
{
Command = ctSmartLinkUnSetupCommand,
CorrelatedId = "",
Data = _sgdpResolverService.GetSGDPSetup().JsonResult
};
_logService.NotifyLogInfo(Properties.Resources.sconTotvsAppUnSetupGravadoNaFila);
_smartLinkPublisherService.AddMessage(parms);
}
public void AddMessageSetup()
{
SmartLinkPublisherAddMessageParams parms = new SmartLinkPublisherAddMessageParams
{
Command = ctSmartLinkSetupCommand,
CorrelatedId = "",
Data = _sgdpResolverService.GetSGDPSetup().JsonResult
};
_logService.NotifyLogInfo(Properties.Resources.sconTotvsAppSetupGravadoNaFila);
_smartLinkPublisherService.AddMessage(parms);
}
}
} |
04. Implementando um consumidor de mensagens
Para que uma classe seja um consumidor de mensagens no SmartLink, deve-se atender aos pré-requisitos listados abaixo:
Pré-requisitos
- Criar um projeto (classLibrary .NET) na solution do segmento em questão, com o seguinte padrão de nome: RM.[Segmento].XXX.SmartLink.Service.
- Exemplo: RM.Glb.SGDP.SmartLink.Service.dll
- Adicionar referência para a dll "RM.Lib.SmartLink.dll";
Criar uma classe herdando da ancestral "RMSSmartLinkConsumerMessageBase".
- A classe "RMSSmartLinkConsumerMessageBase" herda da classe RMSObject da Lib. Consequentemente, as classes de "consumers" poderão chamar os métodos "CreateFacade" e "CreateModule" dentro de suas estruturas.
Carimbar a classe com o atributo "RMSSmartLinkConsumerMessageAttr". Nesse atributo, devem ser informados os dados abaixo:
Propriedade Descrição Cod.Sistema Identificador da aplicação Comando Nome do Comando da mensagem - Para realização de tratamento de exceções no caso de ocorrer erro no processamento da mensagem
Quando for considerado um erro e um nova tentativa de processamento deve ser realizada:
A classe RMSSmartLinkConsumerMessageException ou outra, pode ser utilizada.
Neste caso a mensagem será reenfileirada e novas tentativas de processamento serão realizadas.
Sendo considerado que a mensagem deve ser descartada, ou seja, esta mensagem não deve ser processada neste momento ou apenas sob intervenção manual:
A classe RMSSmartLinkConsumerFatalException, deverá ser utilizada e informado o motivo.
Neste caso a mensagem será colocada em um fila de espera (DLQ) e somente será reprocessada por uma intervenção manual ou será descartada. - Criar um projeto (classLibrary .NET) na solution do segmento em questão, com o seguinte padrão de nome: RM.[Segmento].XXX.SmartLink.Service.
- Exemplo: RM.Glb.SGDP.SmartLink.Service.dll
- Adicionar referência para a dll "RM.Lib.SmartLink.dll";
Criar uma classe herdando da ancestral "RMSSmartLinkConsumerMessageBase".
- A classe "RMSSmartLinkConsumerMessageBase" herda da classe RMSObject da Lib. Consequentemente, as classes de "consumers" poderão chamar os métodos "CreateFacade" e "CreateModule" dentro de suas estruturas.
Carimbar a classe com o atributo "RMSSmartLinkConsumerMessageAttr". Nesse atributo, devem ser informados os dados abaixo:
Propriedade Descrição Cod.Sistema Identificador da aplicação Comando Nome do Comando da mensagemCódigo fonte de exemplo (extraído da classe "GlbSGDPConsumerDataCommandMessage" localizada na solution de Globais, projeto "RM.Glb.SGDP.SmartLink.Service":
Bloco de código language c# firstline 1 linenumbers true using RM.Glb.SGDP.SmartLink.Service.Domain.Interfaces; using RM.Lib; using RM.Lib.SmartLink.Domain; using RM.Lib.SmartLink.Domain.Consumer; using RM.Lib.SmartLink.Domain.Interfaces; using RM.Lib.SmartLink.Domain.Publisher; using System; using System.Runtime.Serialization; namespace RM.Glb.SGDP.SmartLink.Service.Domain { /// <summary> /// Regras de implementação do mecanismo de processamento da mensagem SGDDataCommand do SGDP /// </summary> [RMSSmartLinkConsumerMessageAttr(CodSistema.Glb, "SGDPDataCommand")] public class GlbSGDPConsumerDataCommandMessage : RMSSmartLinkConsumerMessageBase { protected override ConsumerMessageExecuteResult DoExecute(string message) { logService.NotifyLogInfo(Properties.Resources.sconTotvsAppInicioExecucaoDoConsumerSGDPDataCommandConsumer); ConsumerMessageExecuteResult result = new ConsumerMessageExecuteResult(); IGlbSGDPResolverService resolver = GlbSGDPResolveFactory.NewSGDPResolve(this.DBS, this.logService); IRMSSmartLinkPublisherService smartLinkPublisherService = RMSSmartLinkPublisherFactory.NewSmartLinkPublisher(this.DBS, this.logService); IGlbSGDPPublisherMessageService publisher = new GlbSGDPPublisherMessageService(smartLinkPublisherServicethis.SmartLinkPublisherService, resolver, logService); ExecuteDataCommandParms par = new ExecuteDataCommandParms(); par.Message = message; try { var execDataResult = resolver.ExecuteSGDPDataCommand(par); logService.NotifyLogInfo(Properties.Resources.sconTotvsAppJSonSGDPDataResponseCommandForamGerados, "Quantidade JSons Gerados" Properties.Resources.sconTotvsAppQuantidadeDeJSonsGerados, execDataResult?.JsonResults?.Count); result.CorrelatedID = execDataResult.RequestId; if (execDataResult?.JsonResults != null) { foreach (var jsonResult in execDataResult.JsonResults) { AddResponseDataCommandParms parResponse = new AddResponseDataCommandParms(); parResponse.Message = jsonResult; parResponse.CorrelatedId = execDataResult.RequestId; publisher.AddResponseDataCommand(parResponse); } } } catch(Exception ex) { logService.NotifyLogError(new GlbSGDPConsumerDataCommandMessageException( Properties.Resources.sconTotvsAppErroAoProcessarSGDDataCommand, ex)); } logService.NotifyLogInfo(Properties.Resources.sconTotvsAppFimExecucaoDoConsumerSGDPDataCommandConsumer); return result; } } [Serializable] public class GlbSGDPConsumerDataCommandMessageException : RMSApplicationException { public GlbSGDPConsumerDataCommandMessageException() : base() { } public GlbSGDPConsumerDataCommandMessageException(string message) : base(message) { } public GlbSGDPConsumerDataCommandMessageException(string message, Exception ex) : base(message, ex, string.Empty) { } public GlbSGDPConsumerDataCommandMessageException(SerializationInfo info, StreamingContext context) : base(info, context) { } } }
05. Diagrama de classes
06. Diagrama de classes
07. DER
} }
05. Diagrama de classes
06. DER
Tabela | |
---|---|
GTOTVSLINKMESSAGE | Tabela utilizada para armazenar todos as mensagens geradas e enviadas para execução pelo SmartLink. Sempre que uma mensagem é executa com sucesso, a linha referente a mensagem é excluída dessa tabela , deixando essa tabela sempre leve. Esse procedimento melhora a performance do processo, visto que vários "updates" são realizados nessa tabela.Quando menor o volume de uma tabela, mais rápido será a operação do update. |
GTOTVSLINKMESSAGEEXEC | Tabela contendo todos os dados de execução de uma determinada mensagem. |
GTOTVSLINKLOG | Tabela contendo todos os logs de execução de uma mensagem. |
...