Gestão de Processos Assíncronos
As parametrizações descritas neste manual terão impacto nas operações mencionadas na documentação da tela Consulta de Requisições (F660REQ). Estas configurações permitem que o ERP gerencie a execução de processos assíncronos, controlando o número de requisições enviadas ao middleware.
- Seniorconfigcenter: em Middleware -> Web 5.0 -> Processos automáticos, habilite a opção "Habilitar agendador de processos automáticos".
- F000PGS: através do parâmetro global QtdLimReq, defina o limite máximo de requisições em processamento no middleware.
- F000AGE: cadastre um processo automático do tipo Rotina com o código "Rotina Sapiens" = 173 e, no botão Agendar, especifique a frequência de atualização da fila de execução.
- Exemplo:
- Execução da integração contábil mensal (30 dias), com requisições diárias.
Parâmetro QtdLimReg = 10
Periodicidade do processo automático = Hora - Neste cenário, serão criadas 30 requisições para serem enviadas ao middleware.
- Apenas serão executadas, no máximo, 10 requisições simultaneamente, conforme definido no parâmetro global. As demais permanecerão em fila de espera para execução.
- De acordo com a periodicidade do processo automático, a cada hora o ERP verificará quantos processos estão em execução no momento. Caso este número seja menor que a quantidade definida no parâmetro global, o sistema iniciará a execução de outros processos que estavam na fila de espera, até alcançar o limite estabelecido. Ou seja, se estiverem sendo executados apenas 8 processos, serão iniciados mais 2. Atualmente, a gestão da fila de execução não considera a quantidade de instâncias disponíveis, mas apenas o valor definido no parâmetro global.
- No log do processo agendado, serão exibidas as seguintes informações:
- Quantidade de instâncias configuradas no parâmetro global QtdLimReq
- Quantidade de requisições em processamento
- Quantidade de requisições enviadas
- A gestão dessa fila de execução permanece ativa enquanto houver requisições pendentes.
- Execução da integração contábil mensal (30 dias), com requisições diárias.
- F660REQ: Esta tela permite consultar o plano de execução e o status de cada processo. Além disso, possibilita o cancelamento ou a priorização de requisições que estejam na fila para execução.
Fluxograma do processo
Gerenciamento assíncrono de web services customizados
A fim de contemplar os novos recursos do gerenciador de requisições assíncronas, foram desenvolvidas funções para programadores, de modo a permitir a execução de web services customizados a partir dele
Funções
AgendarExecucaoWebservice
Permitir que o usuário insira um novo web services na fila de gerenciamento de requisições
Sintaxe
AgendarExecucaoWebservice(Numero pCodEmp, Alfa pAbrFil, Alfa pWebService, Alfa pPorta, Alfa pJSON);
Parâmetros:
Nome | Tipo | Descrição |
---|---|---|
pCodEmp |
Número |
Código da empresa que será gravado na E000PLE |
pAbrFil |
Alfa |
Abrangência de filiais que será gravado na E000PLE |
pWebService |
Alfa |
Caminho do webservice que será executado. Ex: com.senior.g5.co.mct.ctb.integracao |
pPorta |
Alfa |
Porta do webservice que será executado. Ex: Integrar_8 |
pJson |
Alfa |
JSON contendo o nome dos parâmetros e seus respectivos valores |
Observação
É de extrema importância que os parâmetros enviados no JSON representem uma requisição única. Caso seja enviada uma requisição com parâmetros e valores IGUAIS, e exista uma requisição com os mesmos parâmetros na fila para envio, o sistema cancelará a requisição anterior e executará apenas a última que foi enviada.
Sintaxe:AgendarExecucaoWebserviceEx(Numero pCodEmp, Alfa pAbrFil, Alfa pWebService, Alfa pPorta, Alfa pJSON, Numero End pIdePle)
Parâmetros:
Nome | Tipo | Descrição |
---|---|---|
pCodEmp | Numero | Código da empresa que será gravado na E000PLE |
pAbrFil | Alfanumérico | Abrangência de filiais que será gravado na E000PLE |
pWebService | Alfanumérico | Caminho do web services que será executado. Ex: com.senior.g5.co.mct.ctb.integracao |
pPorta | Alfanumérico | Porta do web services que será executado. Ex: Integrar_8 |
pJson | Alfanumérico | JSON contendo o nome dos parâmetros e seus respectivos valores |
pIdePle | Alfanumérico | Código identificador da requisição gerada (E000PLE.IDEUNI) |
Observação
É de extrema importância que os parâmetros enviados no JSON representem uma requisição única. Caso seja enviada uma requisição com parâmetros e valores IGUAIS, e exista uma requisição com os mesmos parâmetros na fila para envio, o sistema cancelará a requisição anterior e executará apenas a última que foi enviada.
Sintaxe: alterarStatusPlanoExecucao(Numero pIdePle, Numero pStsReq);
Parâmetros:
Nome | Tipo | Descrição |
---|---|---|
pIdePle |
Numero |
Identificador do plano de execução. |
pStsReq |
Numero |
Status da requisição:
Somente permite alterar o status para 2 - Em andamento ou 3 - Finalizado
|
Sintaxe:InserirPassoPlanoExecucao(Numero pIdePle; alfa pMensagem)
Parâmetros:
Nome | Tipo | Descrição |
---|---|---|
pIdePle | Numero | Código do identificador do plano de execução (E000PLE.IDEUNI) |
pMensagem | Alfanumérico | Mensagem a ser exibida no detalhamento do processo |
JSON
O uso do formato JSON para os campos é o padrão adotado; é um modelo de estrutura de pares chave-valor, sendo um formato de dados mais conciso e de fácil interpretação. Um exemplo de modelo no formato XML seria:
<user> |
O modelo JSON seria representado da seguinte forma:
{ "user": { "id": "11", "animal": "Bob", "idade": “2” } } |
Exemplo de uso:
Para exemplificar como utilizar o recurso, teremos uma regra em LSP que irá buscar de uma tabela de usuário, pedidos para serem integrados em um web services customizado.
Regra
Para o exemplo abaixo, selecionamos todos os pedidos que existem na tabela de usuários USU_TPROCESSOS, que estão com status (USU_STATUS) pendente (P). Após agendar a execução no web services, retornamos o identificador da requisição gerada, para que, no web services, possamos processar os pedidos daquele lote. Sendo assim, é realizado o update na USU_TPROCESSOS, passando o identificador para os pedidos selecionados.
Definir Alfa xSQL; Definir Alfa xIdentificador; Definir Alfa xCur_Pedidos; Definir Numero xQtdPendente; Definir Alfa xIdentificadores; Definir Alfa xIdentificadoresJSON; Definir Alfa xJSON; Definir Numero xQtdPedidosEnviar; Definir Alfa xAbrFil; Definir Numero xTamanho; Definir Numero xErro; Definir Alfa xMensagemErro; Definir numero xIdePle; Definir alfa aIdePle; xIdentificadores = ""; xIdentificadoresJSON = ""; IntParaAlfa(CodFil, xAbrFil); xQtdPedidosEnviar = 0; xSQL = "SELECT USU_IDENTF, USU_DATGER FROM USU_TPROCESSOS WHERE USU_TIPPROC = 'P' AND USU_STATUS = 'P' ORDER BY USU_DATGER"; SQL_Criar(xCur_Pedidos); SQL_DefinirComando(xCur_Pedidos, xSQL); SQL_AbrirCursor(xCur_Pedidos); /* Irá retornar todos os pedidos com status pendente de importação */ Enquanto (SQL_EOF(xCur_Pedidos) = 0) Inicio SQL_RetornarAlfa(xCur_Pedidos, "USU_IDENTF", xIdentificador); xIdentificadores = xIdentificadores + "'" + xIdentificador + "',"; xIdentificadoresJSON = xIdentificadoresJSON + xIdentificador + ","; xQtdPedidosEnviar++; Se (xQtdPedidosEnviar = 3) Inicio /* Aqui removemos a ultima virgula na string que serão os parâmetros, nesse caso não seria necessário utilizar os identificadores como parâmetros */ /* mas estou informando para manter a unicidade da requisição */ TamanhoAlfa(xIdentificadores, xTamanho); xTamanho--; CopiarStr(xIdentificadores, 1, xTamanho); TamanhoAlfa(xIdentificadoresJSON, xTamanho); xTamanho--; CopiarStr(xIdentificadoresJSON, 1, xTamanho); /* Parametros que são enviados para o webservice PS: DEVE ter o mesmo nome do parâmetro do WS */ xJSON = "{\"Identificadores\": \""+xIdentificadoresJSON+"\"}"; /* Gera a requisição que será enviada pro gerenciador assíncrono executar */ AgendarExecucaoWebserviceEx(CodEmp, xAbrFil, "ainternal.custom.pedido.integrar", "executar", xJSON, xIdePle); IntParaAlfa(xIdePle, aIdePle); xSQL = "UPDATE USU_TPROCESSOS SET USU_IDEPLE = "+aIdePle+" WHERE USU_IDENTF in ("+xIdentificadores+")"; ExecSQLEX(xSQL, xErro, xMensagemErro); xQuantidadeRequisicoesGerar--; xQtdPedidosEnviar = 0; xIdentificadores = ""; xIdentificadoresJSON = ""; Fim; SQL_Proximo(xCur_Pedidos); Se ((SQL_EOF(xCur_Pedidos) <> 0) e (xQtdPedidosEnviar > 0)) Inicio TamanhoAlfa(xIdentificadores, xTamanho); xTamanho--; CopiarStr(xIdentificadores, 1, xTamanho); TamanhoAlfa(xIdentificadoresJSON, xTamanho); xTamanho--; CopiarStr(xIdentificadoresJSON, 1, xTamanho); /* Parametros que são enviados para o webservice PS: DEVE ter o mesmo nome do parâmetro do WS */ xJSON = "{\"Identificadores\": \""+xIdentificadoresJSON+"\"}"; /* Gera a requisição que será enviada pro gerenciador assíncrono executar */ AgendarExecucaoWebserviceEx(CodEmp, xAbrFil, "", "", xJSON, xIdePle); ExecSQLEX("UPDATE USU_TPROCESSOS SET USU_IDEPLE = :xIdePle WHERE USU_IDENTF in (:xIdentificadores)", xErro, xMensagemErro); xQtdPedidosEnviar = 0; xIdentificadores = ""; xIdentificadoresJSON = ""; Fim; Fim; SQL_FecharCursor(xCur_Pedidos); SQL_Destruir(xCur_Pedidos); |
Web services customizado
Ainternal.custom.pedido.integrar
Neste web services, iremos retornar todos os pedidos da tabela USU_TPROCESSOS que têm o campo USU_IDEPLE igual ao identificador da requisição que será executada. Assim, serão retornados todos os pedidos para integração que pertencem a essa requisição
definir alfa xIdentificador; definir numero xQuantidade; definir numero xLinhaAtual; Definir alfa xMensagemErro; definir alfa xCursorDados; Definir Numero xErro; Definir Numero nIdentificador; Definir Alfa xStatus; Definir Alfa xIdePle; Definir Numero nIdePle; Definir Alfa xSQL; Definir Alfa xCursor; Definir alfa xMensagem; definir interno.com.senior.g5.co.mcm.ven.pedidos.GravarPedidos_13 wsped; nIdePle = executar.IdePle; IntParaAlfa(nIdePle, xIdePle); xLinhaAtual = 0; /* Altera o status da requisição pra Em Andamento, permitindo que saia da fila de execução */ AlterarStatusPlanoExecucao(nIdePle, 2); /* Altera o status na tabela de pedido indicando que os pedidos estão em processamento */ xSQL = "UPDATE USU_TPROCESSOS SET USU_STATUS = 'EP', USU_DATINI = GETDATE() WHERE USU_IDEPLE = "+ xIdePle; ExecSQLEX(xSQL, xErro, xMensagemErro); /* Recupera todos os pedidos que serão processados naquela requisição */ xSQL = "SELECT * FROM USU_TPROCESSOS WHERE USU_IDEPLE = " +xIdePle; SQL_Criar(xCursor); SQL_DefinirComando(xCursor, xSQL); SQL_AbrirCursor(xCursor); /* Adicionar um passo de execução do pedido que está sendo integrado */ InserirPassoPlanoExecucao(nIdePle, "Carregando pedidos..."); Enquanto (SQL_EOF(xCursor) = 0) inicio /* Adiciona na grid do WS interno os pedidos que serão integrados */ SQL_RetornarAlfa(xCursor, "USU_IDENTF", xIdentificador); wsped.Pedido.CriarLinha(); wsped.Pedido.opeExe = "1"; wsped.Pedido.CodEmp = 1; wsped.Pedido.CodFil = 1; wsped.Pedido.NumPed = 5; wsped.Pedido.IdeExt = xIdentificador; xLinhaAtual++; SQL_Proximo(xCursor); fim; SQL_FecharCursor(xCursor); SQL_Destruir(xCursor); Se (wsped.Pedido.QtdLinhas > 0) Inicio /* Adicionar um passo de execução do pedido que está sendo integrado */ InserirPassoPlanoExecucao(nIdePle, "Executando importação do pedido"); wsped.modoExecucao = 1; wsped.executar(); xLinhaAtual = 0; xQuantidade = wsped.respostaPedido.QtdLinhas; Enquanto (xLinhaAtual < xQuantidade) Inicio wsped.respostaPedido.LinhaAtual = xLinhaAtual; nIdentificador = wsped.respostaPedido.IdeExt; IntParaAlfa(nIdentificador, xIdentificador); Se (wsped.respostaPedido.tipRet = 1) Inicio xMensagem = "Pedido id "+ xIdentificador+" importado com sucesso"; /* Adicionar um passo de execução do pedido que está sendo integrado */ InserirPassoPlanoExecucao(nIdePle, xMensagem); xStatus = "C"; xMensagemErro = "OK"; Fim Senao Inicio xStatus = "E"; xMensagem = "Pedido id "+ xIdentificador+" importado com erro. Mensagem: " + wsped.respostaPedido.retorno; /* Adicionar um passo de execução do pedido que está sendo integrado */ InserirPassoPlanoExecucao(nIdePle, xMensagem); Fim; xSQL = "UPDATE USU_TPROCESSOS SET USU_STATUS = :xStatus, USU_DATINI = GETDATE(), USU_MSGLOG = :xMensagemErro WHERE USU_IDEPLE =" + xIdentificador; ExecSQLEX(xSQL, xErro, xMensagemErro); xLinhaAtual++; Fim; Fim; /* Altera o status da requisição pra Finalizado */ AlterarStatusPlanoExecucao(nIdePle, 3); |