Definição da Regra de Negócio
Visão Geral
O novo modelo de sincronização, em oposição à atual técnica de pushing (empurrar, em português), utiliza a técnica de pulling (puxar), que consiste em requisições periódicas do Datasul ao Identity, com o objetivo de consumir uma fila de operações pendentes. Havendo itens nesta fila, o Datasul os recupera, efetivando-os no banco de dados. Por fim, sinaliza para o Identity que a operação foi replicada com sucesso, o qual remove a operação pendente da fila.
As operações realizadas no Identity serão encaminhadas para duas filas: de aplicativo e de usuários. A fila de aplicativo conterá operações como:
- Criação de papel (grupo de segurança) no aplicativo;
- Alteração de dados do papel;
- Eliminação do papel;
- Habilitar consulta rápida ou item de menu no papel do aplicativo;
- Desabilitar consulta rápida ou item de menu no papel do aplicativo.
A fila de usuários conterá operações como:
- Associar (provisionar) um usuário ao aplicativo;
- Desassociar (desprovisionar) um usuário do aplicativo;
- Provisionar um usuário a um papel do aplicativo;
- Desprovisionar um usuário de um papel do aplicativo;
- Provisionar uma empresa do aplicativo a um usuário;
- Desprovisionar uma empresa do aplicativo de um usuário.
Em relação a fila de usuários, será possível consultar previamente a lista de usuários que possuem operações pendentes no Identity. Com esta lista, o Datasul poderá buscar apenas as operações de um usuário específico, quando necessário.
A recuperação das operações pendentes nas filas ocorrerá de duas formas:
- Periodicamente, em intervalos de 15 segundos para a fila do aplicativo, e intervalos de 30 segundos, para a fila de usuários;
- Quando o usuário acessar o Datasul.
A recuperação periódica iniciará assim que o servidor de aplicação do Datasul (JBoss) for iniciado, caso o modo "pull" esteja ativado. Os valores dos intervalos são sugestões iniciais, que podem ser alteradas pelo usuário administrador. Serão recuperadas as operações de ambas as filas. Ao recuperar as operações da fila de usuários, serão consideradas as de todos os usuários.
A recuperação das operações no momento do acesso ao Datasul também se dará para ambas as filas. Entretanto, para a fila de usuários, serão consideradas apenas as operações do usuário que está acessando o Datasul.
Em termos de performance, o modo "pull" parece ter um impacto maior no volume de dados trafegado ao longo do tempo por conta das requisições frequentes. Neste aspecto cabem duas considerações:
- A frequência com que as filas serão consultadas e as operações recuperadas poderão ser ajustadas pelo administrador do Datasul. Com isso, pode-se alterar os valores para aqueles que ofereçam o melhor equilíbrio entre volume total de dados num intervalo de tempo e a velocidade para disponibilizar as informações no ERP;
- As requisições geradas pelo Identity possuem uma "carga" de dados pequena (não mais que algumas dezenas de kilobytes), visando justamente o seu rápido processamento.
Conforme pode ser visto mais adiante na parte da implementação, o processamento das operações será feito de forma paralela ao recebimento, justamente com o objetivo de oferecer o menor impacto na performance geral do produto.
A ativação do modo "pull" se dará, primeiramente, pela configuração do aplicativo no Identity, o qual passará a enviar as operações para as filas citadas, em vez de fazer requisições diretas ao Datasul. No lado do Datasul, a ativação ocorrerá atualizando-se as configurações realizadas no Identity através do Fluig Configurator, pelo recurso "One Click Configuration". Com isso, o serviço de busca das operações é iniciado, respeitando a periodicidade definida.
O serviço de busca das operações, no lado do Datasul, pode ser interrompido a qualquer tempo, editando o parâmetro correspondente no Fluig Configurator. Porém, isso não altera a parametrização do lado do Identity, que continuará enfileirando as operações realizadas. Para desativar o modo "pull" no Identity, será necessário alterar o parâmetro correspondente nas configurações do aplicativo. Em contrapartida, a desativação do modo "pull" do lado do Identity, fará com que as operações sejam enviadas diretamente ao Datasul (modo "push"), que as receberá sem maiores problemas, enquanto, paralelamente, o serviço de busca de operações se manterá ativo, fazendo pesquisas periódicas sem trazer qualquer dado.
Após o processamento das operações, o Datasul comunicará o Identity que aquela operação foi processada com sucesso e pode ser removida da fila. Caso haja algum erro no processamento da operação, ela será mantida na fila do Identity, para ser processada novamente em outra oportunidade. Em caso de erro recorrente da operação, o serviço de busca deve ser interrompido e o usuário administrador deve ser notificado (por e-mail e por mensagem no menu do ERP) para que possa atuar corretivamente, restabelecendo a normalidade do processo.
Arquitetura
Tecnicamente, a solução que implementa o modo "pull" no Datasul está organizada conforme demonstra a figura 4 da seção Fluxo do Processo.
Os componentes e suas respectivas funções estão descritos a seguir:
- Fluig Configurator: é o responsável por fornecer a interface de gerenciamento do serviço de busca de operações, permitindo parar ou iniciar o mesmo, bem como verificar o status. É também pelo Fluig Configurator que se ativa e desativa o modo "pull".
- FluigPullControllerResource: fornece as APIs REST para iniciar, parar e verificar o status do serviço de busca das operações. Por estar desacoplado do Fluig Configurator, pode ser acionado por qualquer outro recurso que implemente o padrão REST.
- FluigPullApplicationListener: é o responsável por iniciar o serviço de busca das operações quando o servidor de aplicação do Datasul é iniciado, desde que o modo "pull" esteja ativado.
- FluigPuller: implementa o serviço de busca das operações. É responsável por consultar as filas do Identity, buscar as operações para processamento e avisar ao Identity quando a operação foi processada com sucesso.
- OperationProcessor: é o responsável por processar as operações obtidas, encaminhando-as para as rotinas correspondentes do Datasul.
Implementação
a) Fluxo básico
O Fluig Configurator exibirá um novo campo - Modo Pull - na aba Configurações (ver figura 1 da seção Protótipo de Tela), que exibirá o valor informado nas configurações do aplicativo no Identity, podendo ser modificado para desabilitar temporariamente o modo "pull" do lado do Datasul. Essa alteração também será refletida no arquivo fluig.properties, com a adição da propriedade identity.pullMode, cujos valores possíveis serão "true" ou "false".
Ao salvar as alterações realizadas pelo Fluig Configurator, o serviço de busca das operações deve ser ativado ou desativado conforme o valor da propriedade identity.pullMode. Isso será feito pela classe Java SettingsService, que efetuará a chamada ao serviço REST correspondente (fluig-pull/service/start ou fluig-pull/service/stop), implementado pela classe com.totvs.fluig.idm.pull.resource.FluigPullControllerResource.
A classe FluigPullControllerResource disponibilizará os seguintes serviços REST para gerenciamento do serviço de busca de operações:
- Start (GET /fluig-pull/service/start): inicia o serviço. Retorna "true" quando o modo "pull" está ativado e o serviço foi iniciado com sucesso; e "disabled" quando o modo "pull" estiver desabilitado.
- Stop (GET /fluig-pull/service/stop): interrompe o serviço. Retorna "true" quando encerrado com sucesso e "false" caso não seja possível encerrar o serviço.
- Status (GET /fluig-pull/service/status): retorna o status do serviço. Valores possíveis de retorno são "alive", quando o serviço estiver em execução; "stopped", quando estiver parado; e "disabled" quando o modo "pull" estiver desabilitado.
- Errors (GET /fluig-pull/service/errors): retorna os erros ocorridos durante a execução do serviço.
A classe com.totvs.fluig.idm.pull.FluigPuller, que implementa o serviço de busca de operações, terá os seguintes métodos:
- startPull, para iniciar o serviço de busca das operações;
- stopPull, para interromper o serviço de busca das operações;
- isRunning, para verificar se o serviço de busca está em execução;
- checkAppQueue, para recuperar as operações pendentes para o aplicativo;
- checkUserQueue, para recuperar as operações pendentes para o usuário;
- clearAppQueue, para limpar a fila de operações do aplicativo;
- clearUserQueue, para limpar a fila de operações dos usuários;
- hasErrors, para verificar se houve erro no processamento das operações;
- getErrors, para obter os erros ocorridos;
- clearErrors, para limpar a lista de erros.
Os métodos checkAppQueue e checkUserQueue, nas execuções periódicas, serão chamados por threads iniciadas quando o método startPull for chamado. Neste caso, a verificação será feita de forma assíncrona (veja a figura 5 para mais detalhes).
Na verificação a partir do login do usuário no Datasul, os métodos de verificação serão chamados de forma síncrona pela classe com.totvs.fluig.idm.servlet.AssertionConsumerServlet, no método receiveResponse, quando a requisição SAML recebida do Identity possuir os atributos appsChanged e entitlementsChanged com valores iguais a "true" (ver figura 6).
A classe FluigPuller utilizará o REST client, versão 1.5.0, disponibilizado pela equipe do Identity, para consumir os serviços REST necessários para verificação e consumo das filas de operação. A classe que implementa o REST client é com.totvslabs.idm.rest.client.FluigIdentityRestClient. Os métodos que serão utilizados estão listados abaixo:
Tarefa | Método | Parâmetros | Retorno |
---|
Obter as operações pendentes para o aplicativo | client.getCompanyAppService().getPendingOperationsForApplication() | String companyId String applicationId | List<PendingOperationsDTO> |
Endpoint no Identity: GET /rest/v2/companies/{companyId}/apps/{appId}/pending-app-operations |
Obter os usuários com operações pendentes | client.getCompanyAppService().getPendingUsersForApplication() | String companyId String applicationId | List<String> |
Endpoint no Identity: GET /rest/v2/companies/{companyId}/apps/{appId}/pending-app-users |
Obter operações pendentes para o usuário | client.getCompanyUserService().getPendingUserOperationsForApplication() | String companyId String userId String applicationId | List<PendingOperationsDTO> |
Endpoint no Identity: GET /rest/v2/companies/{companyId}/users/{userId}/apps/{appId}/pending-user-operations |
Limpar a fila de operações do aplicativo | client.getCompanyAppService().clearPendingOperationsForApplication() | String companyId String applictionId List<String> operationIds | boolean |
Endpoint no Identity: POST /rest/v2/companies/{companyId}/apps/{appId}/clear-app-operations |
Limpar a fila de operações do usuário | client.getCompanyUserService().clearPendingUserOperationsForApplication() | String companyId String userId String applicationId List<String> operationIds | boolean |
Endpoint no Identity: POST /rest/v2/companies/{companyId}/users/{userId}/apps/{appId}/clear-user-app-operations |
A classe com.totvslabs.idm.common.model.PendingOperationsDTO conterá os dados das operações obtidas do Identity. Dependendo do valor contido no atributo operationName, o Datasul, através da classe com.totvs.fluig.idm.pull.OperationProcessor, direcionará a operação para a rotina de processamento correspondente. A implementação do modo "push" concentrou o processamento das operações nos serviços REST chamados diretamente pelo Identity e implementados pelas classes com.totvs.fluig.user.resource.UserResourceSCIMv2, com.totvs.fluig.resource.resource.ResourceResouce e com.totvs.fluig.entitlements.resource.EntitlementsResource. Com desenvolvimento do modo "pull", será necessário desacoplar as lógicas de processamento, colocando-as em novas classes, para que sejam reutilizadas pela classe OperationProcessor. As classes originais, dos serviços REST do modo "push", passarão a utilizar as novas classes também. A seguir, a relação entre as classes:
Método | Classe Original | Nova Classe |
createUser | UserResourceSCIMv2 | com.totvs.fluig.user.service.UserGroupConnector |
inactivateUser | UserResourceSCIMv2 | com.totvs.fluig.user.service.UserGroupConnector |
createResource | ResourceResouce | com.totvs.fluig.resource.service.ResourceConnector |
updateResource | ResourceResouce | com.totvs.fluig.resource.service.ResourceConnector |
deleteResource | ResourceResouce | com.totvs.fluig.resource.service.ResourceConnector |
linkResource | ResourceResouce | com.totvs.fluig.resource.service.ResourceConnector |
unlinkResource | ResourceResouce | com.totvs.fluig.resource.service.ResourceConnector |
addEntitlements | EntitlementsResource | com.totvs.fluig.user.service.UserGroupConnector |
removeEntitlements | EntitlementsResource | com.totvs.fluig.user.service.UserGroupConnector |
Para cada operação obtida, haverá um tipo de dado associado (atributo dataType), que definirá a forma como os dados da operação, presentes no atributo data, estarão estruturados. Na tabela a seguir, é possível ver o relacionamento entre o nome da operação e o tipo de dado (e a respectiva classe Java), bem como o método de processamento que será utilizado.
Operation Name | Data Type (Class) | Método |
PROVISIONING | FLUIG_USER (com.totvslabs.idm.common.extension.FluigUser) | UserGroupConnector.createUser() |
DEPROVISIONING | USER_ID (String) | UserGroupConnector.inactivateUser() |
CREATE_RESOURCES | RESOURCES_LIST (List<com.totvslabs.idm.common.extension.Resource>) | ResourceConnector.createResource() |
UPDATE_RESOURCES | RESOURCES_LIST (List<com.totvslabs.idm.common.extension.Resource>) | ResourceConnector.updateResource() |
DELETE_RESOURCES | RESOURCES_LIST (List<com.totvslabs.idm.common.extension.Resource>) | ResourceConnector.deleteResource() |
LINK_RESOURCES | RAC_RESOURCES_DTO (com.totvslabs.idm.common.model.RACResourcesDTO) | ResourceConnector.linkResource() |
UNLINK_RESOURCES | RAC_RESOURCES_DTO (com.totvslabs.idm.common.model.RACResourcesDTO) | ResourceConnector.unlinkResource() |
ADD_ENTITLEMENTS | RAC_RESOURCES_DTO_LIST (List<com.totvslabs.idm.common.model.RACResourcesDTO>) | UserGroupConnector.addEntitlements() |
REMOVE_ENTITLEMENTS | RAC_RESOURCES_DTO_LIST (List<com.totvslabs.idm.common.model.RACResourcesDTO>) | UserGroupConnector.removeEntitlements() |
Em caso de erro no processamento das operações, o serviço de busca será interrompido pela classe OperationProcessor, que efetuará uma chamada ao método stopPull() da classe FluigPuller. Os erros também serão repassados à classe FluigPuller, os quais poderão ser recuperados pelo método getErrors().
A limpeza das filas no Identity ocorrerá após a classe OperationProcessor receber o retorno positivo do método responsável pelo processamento da operação. Será efetuada a chamada aos métodos clearAppQueue() e clearUserQueue() da classe FluigPuller, passando a lista das operações processadas e o usuário, no caso do segundo método.
b) Monitoramento e controle
Para controle do serviço de busca (parada e inicio), o Fluig Configurator disponibilizará uma nova aba, chamada Gerenciamento, (ver Figura 2) na qual constará:
- Botão para parar/iniciar o serviço.
- Campo para mostrar o status atual do serviço.
- Campo para mostrar os erros ocorridos na execução do serviço de busca.
O botão só estará habilitado se o modo "pull" estiver habilitado. O botão alterará o seu label conforme o status atual do serviço. Se o serviço estiver parado, será exibido o texto "Iniciar". Se estiver executando, será exibido o texto "Parar". Ao lado do botão será exibido o texto do status atual (Executando/Parado). A determinação do status atual será feita consultando o serviço REST Status (/fluig-pull/service/status), conforme comentado no item a) Fluxo básico.
O campo para mostrar os erros ocorridos será alimentado com as informações provenientes do serviço REST Errors (/fluig-pull/service/errors). O retorno do serviço terá formato semelhante ao mostrado abaixo:
[
{ "origin" : "setup", "message" : "Texto da mensagem de erro" },
{ "origin" : "startPull", "message" : "Texto da mensagem de erro" },
{ "origin" : "9843ld0d-29302s-akj20ld0" : "Texto da mensagem de erro" }
]
Onde:
- origin: indica a origem do erro, que pode ser o ID da operação em processamento, ou uma das partes do processo de busca das operações que antecede o processamento;
- message: texto da mensagem de erro.
Os erros exibidos pelo Fluig Configurator também serão gravados em um arquivo a parte, juntamente com outros eventos relacionados à integração entre o ERP e o Identity. Este arquivo será chamado fluig-integration.log e o mesmo poderá ser baixado através de link disponibilizado na aba Gerenciamento. Sua geração dependerá de configuração específica no arquivo jboss-log4j.xml (localizado em <dir_inst_datasul>\jboss-4.2.3.GA\server\<instancia>\conf) que deverá ser alterado conforme sugerido a seguir:
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
(...)
<!-- A size based file rolling appender -->
<appender name="FLUIG" class="org.jboss.logging.appender.RollingFileAppender">
<errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
<param name="File" value="${jboss.server.log.dir}/fluig-integration.log"/>
<param name="Append" value="false"/>
<param name="MaxFileSize" value="100MB"/>
<param name="MaxBackupIndex" value="5"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5r %-5p (%t:%x) [%c{1}] %m%n"/>
</layout>
</appender>
(...)
<logger name="com.totvs.fluig">
<level value="INFO" />
<appender-ref ref="FLUIG"/>
</logger>
(...)
</log4j:configuration>
O serviço de busca das operações também emitirá e-mail de notificação caso ocorra erro ao iniciar o serviço ou durante o processamento das operações em fila. O e-mail será enviado para o usuário informado na configuração do aplicativo do Identity, no campo "Nome do Usuário do Administrador do Domínio" da aba "Provisionar".
O e-mail enviado terá o seguinte formato:
(Este é um e-mail automático, e portanto, não monitorado. Não é necessário responder.)
Problema na Integração com Identity
Os erros abaixo causaram a interrupção do serviço de busca das operações no Identity.
As operações realizadas não serão atualizadas no ERP até que o serviço seja restabelecido.
Após a resolução da causa dos erros indicados abaixo,acesse o Fluig Configurator e inicie o serviço.
Para mais detalhes, verifique os arquivos fluig-integration.log e server.log.
Origem | Mensagem |
appQueue | Erro durante verificação da fila: null |
userQueue | Erro durante verificação da fila: null |
©TOTVS - 2015
Para habilitar o envio de e-mail no servidor de aplicação do Datasul, deve-se editar o arquivo mail-service.xml, localizado em <dir_inst_datasul>\jboss-4.2.3.GA\server\<instancia>\deploy. Os parâmetros que devem editados neste arquivo são: