From 9c8fa388693503b9c9ee09f1189c94a7b59d1fa7 Mon Sep 17 00:00:00 2001 From: Guilherme Andrade Del Cantoni Date: Wed, 24 Apr 2019 09:07:27 -0300 Subject: [PATCH] Melhorias gerais no mecanismo de processamento das filas de tarefas --- PENIntegracao.php | 31 +++++++++++++++++++++++++++++-- README.md | 8 ++++---- rn/EnviarReciboTramiteRN.php | 77 ++++++++++++++++++++++++++++++++++++++++++++--------------------------------- rn/PendenciasTramiteRN.php | 19 ++++++++++++++----- rn/ProcessarPendenciasRN.php | 3 +++ rn/ProcessoEletronicoRN.php | 66 ++++++++++++++++++++++++++++++++++++++---------------------------- 6 files changed, 132 insertions(+), 72 deletions(-) diff --git a/PENIntegracao.php b/PENIntegracao.php index 07994bf..a6ba455 100644 --- a/PENIntegracao.php +++ b/PENIntegracao.php @@ -11,7 +11,7 @@ class PENIntegracao extends SeiIntegracao { } public function getVersao() { - return '1.2.0'; + return '1.2.1'; } public function getInstituicao() { @@ -353,11 +353,38 @@ class PENIntegracao extends SeiIntegracao { return $xml; } - public static function validarCompatibilidadeModulo($bolGerarExcecao = true, $strVersaoSEI = SEI_VERSAO) + public static function validarCompatibilidadeModulo($parStrVersaoSEI=null) { + $strVersaoSEI = $parStrVersaoSEI ?: SEI_VERSAO; $objPENIntegracao = new PENIntegracao(); if(!in_array($strVersaoSEI, self::COMPATIBILIDADE_MODULO_SEI)) { throw new InfraException(sprintf("Módulo %s (versão %s) não é compatível com a versão %s do SEI.", $objPENIntegracao->getNome(), $objPENIntegracao->getVersao(), $strVersaoSEI)); } } + + /** + * Método responsável pela validação da compatibilidade do banco de dados do módulo em relação ao versão instalada. + * + * @param boolean $bolGerarExcecao Flag para geração de exceção do tipo InfraException caso base de dados incompatível + * @return boolean Indicardor se base de dados é compatível + */ + public static function validarCompatibilidadeBanco($bolGerarExcecao=true) + { + $objInfraParametro = new InfraParametro(BancoSEI::getInstance()); + $strVersaoBancoModulo = $objInfraParametro->getValor(PenAtualizarSeiRN::PARAMETRO_VERSAO_MODULO, false) ?: $objInfraParametro->getValor(PenAtualizarSeiRN::PARAMETRO_VERSAO_MODULO_ANTIGO, false); + + $objPENIntegracao = new PENIntegracao(); + $strVersaoModulo = $objPENIntegracao->getVersao(); + + $bolBaseCompativel = ($strVersaoModulo === $strVersaoBancoModulo); + + if(!$bolBaseCompativel && $bolGerarExcecao){ + throw new ModuloIncompativelException(sprintf("Base de dados do módulo '%s' (versão %s) encontra-se incompatível. A versão da base de dados atualmente instalada é a %s. \n ". + "Favor entrar em contato com o administrador do sistema.", $objPENIntegracao->getNome(), $strVersaoModulo, $strVersaoBancoModulo)); + } + + return $bolBaseCompativel; + } } + +class ModuloIncompativelException extends InfraException { } diff --git a/README.md b/README.md index f1f06f3..5f02f62 100644 --- a/README.md +++ b/README.md @@ -80,8 +80,8 @@ Estes dois componentes são utilizados para gerenciar a fila de recebimento de n user=apache autostart=true autorestart=true - startsecs=15 - startretries=3 + startsecs=5 + startretries=1000 log_stdout=true log_stderr=true logfile_backups=50 @@ -99,8 +99,8 @@ Estes dois componentes são utilizados para gerenciar a fila de recebimento de n user=apache autostart=true autorestart=true - startsecs=15 - startretries=3 + startsecs=5 + startretries=1000 log_stdout=true log_stderr=true logfile_maxbytes=10MB diff --git a/rn/EnviarReciboTramiteRN.php b/rn/EnviarReciboTramiteRN.php index e1ff95c..7bdab3e 100644 --- a/rn/EnviarReciboTramiteRN.php +++ b/rn/EnviarReciboTramiteRN.php @@ -84,45 +84,57 @@ class EnviarReciboTramiteRN extends InfraRN public function enviarReciboTramiteProcesso($parNumIdTramite, $parArrayHash = null, $parDthRecebimento = null) { - date_default_timezone_set('America/Sao_Paulo'); + try{ + date_default_timezone_set('America/Sao_Paulo'); - if(!isset($parNumIdTramite) || $parNumIdTramite == 0) { - throw new InfraException('Parâmetro $parNumIdTramite não informado.'); - } + if(!isset($parNumIdTramite) || $parNumIdTramite == 0) { + throw new InfraException('Parâmetro $parNumIdTramite não informado.'); + } - //Verifica se todos os componentes digitais já foram devidamente recebido - $arrObjTramite = $this->objProcessoEletronicoRN->consultarTramites($parNumIdTramite); - if(!isset($arrObjTramite) || count($arrObjTramite) != 1) { - throw new InfraException("Trâmite não pode ser localizado pelo identificador $parNumIdTramite."); - } + //Verifica se todos os componentes digitais já foram devidamente recebido + $arrObjTramite = $this->objProcessoEletronicoRN->consultarTramites($parNumIdTramite); + if(!isset($arrObjTramite) || count($arrObjTramite) != 1) { + throw new InfraException("Trâmite não pode ser localizado pelo identificador $parNumIdTramite."); + } - $objTramite = $arrObjTramite[0]; - $strNumeroRegistro = $objTramite->NRE; + $objTramite = $arrObjTramite[0]; + $strNumeroRegistro = $objTramite->NRE; - if($objTramite->situacaoAtual != ProcessoEletronicoRN::$STA_SITUACAO_TRAMITE_COMPONENTES_RECEBIDOS_DESTINATARIO) { - throw new InfraException('Situação do Trâmite diferente da permitida para o envio do recibo de conclusão de trâmite.'); - } + if($objTramite->situacaoAtual != ProcessoEletronicoRN::$STA_SITUACAO_TRAMITE_COMPONENTES_RECEBIDOS_DESTINATARIO) { + throw new InfraException('Situação do Trâmite diferente da permitida para o envio do recibo de conclusão de trâmite.'); + } - $dthRecebimentoComponentesDigitais = $this->obterDataRecebimentoComponentesDigitais($objTramite); - $dthRecebimentoComponentesDigitais = $dthRecebimentoComponentesDigitais ?: date(); - $dthRecebimento = gmdate("Y-m-d\TH:i:s.000\Z", InfraData::getTimestamp($dthRecebimentoComponentesDigitais)); + $dthRecebimentoComponentesDigitais = $this->obterDataRecebimentoComponentesDigitais($objTramite); + $dthRecebimentoComponentesDigitais = $dthRecebimentoComponentesDigitais ?: date(); + $dthRecebimento = gmdate("Y-m-d\TH:i:s.000\Z", InfraData::getTimestamp($dthRecebimentoComponentesDigitais)); - $strReciboTramite = ""; - $strReciboTramite .= "$parNumIdTramite"; - $strReciboTramite .= "$strNumeroRegistro"; - $strReciboTramite .= "$dthRecebimento"; - sort($parArrayHash); + $strReciboTramite = ""; + $strReciboTramite .= "$parNumIdTramite"; + $strReciboTramite .= "$strNumeroRegistro"; + $strReciboTramite .= "$dthRecebimento"; + sort($parArrayHash); - foreach ($parArrayHash as $strHashConteudo) { - if(!empty($strHashConteudo)){ - $strReciboTramite .= "$strHashConteudo"; - } - } - $strReciboTramite .= ""; + foreach ($parArrayHash as $strHashConteudo) { + if(!empty($strHashConteudo)){ + $strReciboTramite .= "$strHashConteudo"; + } + } + $strReciboTramite .= ""; + + //Envia o Recibo de salva no banco + $hashAssinatura = $this->objProcessoEletronicoRN->enviarReciboDeTramite($parNumIdTramite, $dthRecebimento, $strReciboTramite); + $this->cadastrarReciboTramiteRecebimento($strNumeroRegistro, $parNumIdTramite, $hashAssinatura, $parArrayHash); - //Envia o Recibo de salva no banco - $hashAssinatura = $this->objProcessoEletronicoRN->enviarReciboDeTramite($parNumIdTramite, $dthRecebimento, $strReciboTramite); - $this->cadastrarReciboTramiteRecebimento($strNumeroRegistro, $parNumIdTramite, $hashAssinatura, $parArrayHash); + } catch (Exception $e) { + $detalhes = null; + $mensagem = InfraException::inspecionar($e); + + if(isset($strReciboTramite)){ + $detalhes = "Falha na validação do recibo de conclusão do trâmite do processo. Recibo: \n" . $strReciboTramite; + } + + throw new InfraException($mensagem, $e, $detalhes); + } } private function obterDataRecebimentoComponentesDigitais($parObjTramite){ @@ -147,7 +159,7 @@ class EnviarReciboTramiteRN extends InfraRN /** * Consulta o componente digital no barramento. Utilizado para casos de retrasmissão, * onde esta unidade esta recebendo um componente digital que pertence à ela - * própria, então o id_tramite de envio, que foi gravado, é diferente do de recebimento + * própria, então o id_tramite de envio, que foi gravado, é diferente do recebimento * * @param int $numIdTramite * @return array[ComponenteDigitalDTO] @@ -188,7 +200,6 @@ class EnviarReciboTramiteRN extends InfraRN $objDocumentoDTO = $objDocumentoBD->consultar($objDocumentoDTO); if(empty($objDocumentoDTO)) { - $dblIdDocumento = $objDocumentoDTO->getDblIdDocumento(); } } diff --git a/rn/PendenciasTramiteRN.php b/rn/PendenciasTramiteRN.php index 652f9e4..94e8ac7 100644 --- a/rn/PendenciasTramiteRN.php +++ b/rn/PendenciasTramiteRN.php @@ -19,6 +19,7 @@ class PendenciasTramiteRN extends InfraRN { public static function getInstance() { if (self::$instance == null) { + PENIntegracao::validarCompatibilidadeBanco(); self::$instance = new PendenciasTramiteRN(ConfiguracaoSEI::getInstance(), SessaoSEI::getInstance(), BancoSEI::getInstance(), LogSEI::getInstance()); } @@ -72,6 +73,8 @@ class PendenciasTramiteRN extends InfraRN { while (true) { try { + PENIntegracao::validarCompatibilidadeBanco(); + $this->gravarLogDebug('Recuperando lista de pendências do PEN', 1); $arrObjPendenciasDTO = $this->obterPendenciasTramite(); foreach ($arrObjPendenciasDTO as $objPendenciaDTO) { @@ -80,6 +83,12 @@ class PendenciasTramiteRN extends InfraRN { $this->gravarLogDebug($mensagemLog, 3, true); $this->enviarPendenciaFilaProcessamento($objPendenciaDTO); } + + } catch(ModuloIncompativelException $e) { + //Registra a falha no log do sistema e reinicia o ciclo de requisição e + //sai loop de eventos para finalizar o script e subir uma nova versão atualizada + LogSEI::getInstance()->gravar(InfraException::inspecionar($e)); + break; } catch (Exception $e) { //Apenas registra a falha no log do sistema e reinicia o ciclo de requisição LogSEI::getInstance()->gravar(InfraException::inspecionar($e)); @@ -211,22 +220,22 @@ class PendenciasTramiteRN extends InfraRN { $client = new GearmanClient(); $client->addServer("127.0.0.1", 4730); - $strWorkload = strval($objPendencia->getNumIdentificacaoTramite()); + $numIDT = strval($objPendencia->getNumIdentificacaoTramite()); switch ($objPendencia->getStrStatus()) { case ProcessoEletronicoRN::$STA_SITUACAO_TRAMITE_INICIADO: - $client->addTaskBackground('enviarComponenteDigital', $strWorkload, null); + $client->addTaskBackground('enviarComponenteDigital', $numIDT, null, $numIDT); break; case ProcessoEletronicoRN::$STA_SITUACAO_TRAMITE_COMPONENTES_ENVIADOS_REMETENTE: case ProcessoEletronicoRN::$STA_SITUACAO_TRAMITE_METADADOS_RECEBIDO_DESTINATARIO: case ProcessoEletronicoRN::$STA_SITUACAO_TRAMITE_COMPONENTES_RECEBIDOS_DESTINATARIO: - $client->addTaskBackground('receberProcedimento', $strWorkload, null); + $client->addTaskBackground('receberProcedimento', $numIDT, null, $numIDT); break; case ProcessoEletronicoRN::$STA_SITUACAO_TRAMITE_RECIBO_ENVIADO_DESTINATARIO: - $client->addTaskBackground('receberReciboTramite', $strWorkload, null); + $client->addTaskBackground('receberReciboTramite', $numIDT, null, $numIDT); break; case ProcessoEletronicoRN::$STA_SITUACAO_TRAMITE_RECIBO_RECEBIDO_REMETENTE: @@ -236,7 +245,7 @@ class PendenciasTramiteRN extends InfraRN { break; case ProcessoEletronicoRN::$STA_SITUACAO_TRAMITE_RECUSADO: - $client->addTaskBackground("receberTramitesRecusados", $strWorkload, null);; + $client->addTaskBackground("receberTramitesRecusados", $numIDT, null, $numIDT); break; default: diff --git a/rn/ProcessarPendenciasRN.php b/rn/ProcessarPendenciasRN.php index 62dba08..b657df3 100644 --- a/rn/ProcessarPendenciasRN.php +++ b/rn/ProcessarPendenciasRN.php @@ -49,6 +49,9 @@ class ProcessarPendenciasRN extends InfraAgendamentoTarefa while($this->objGearmanWorker->work()) { + PENIntegracao::validarCompatibilidadeBanco(); + + $this->gravarLogDebug("Gearman worker return code: " . $this->objGearmanWorker->returnCode(), 0, true); if ($this->objGearmanWorker->returnCode() != GEARMAN_SUCCESS) { $strErro = 'Erro no processamento de pendências do PEN. ErrorCode: ' . $this->objGearmanWorker->returnCode(); LogSEI::getInstance()->gravar($strErro); diff --git a/rn/ProcessoEletronicoRN.php b/rn/ProcessoEletronicoRN.php index d40f684..94d1f97 100644 --- a/rn/ProcessoEletronicoRN.php +++ b/rn/ProcessoEletronicoRN.php @@ -42,6 +42,10 @@ class ProcessoEletronicoRN extends InfraRN { // 02 a 18 estão registrados na tabela rel_tarefa_operacao public static $OP_OPERACAO_REGISTRO = "01"; + // 10 minutos de timeout para requisições via webservice + const WS_CONNECTION_TIMEOUT = 600; + + const ALGORITMO_HASH_DOCUMENTO = 'SHA256'; /** @@ -106,6 +110,9 @@ class ProcessoEletronicoRN extends InfraRN { , 'passphrase' => $this->strLocalCertPassword , 'resolve_wsdl_remote_includes' => true , 'cache_wsdl'=> WSDL_CACHE_NONE + , 'connection_timeout' => self::WS_CONNECTION_TIMEOUT + , CURLOPT_TIMEOUT => self::WS_CONNECTION_TIMEOUT + , CURLOPT_CONNECTTIMEOUT => self::WS_CONNECTION_TIMEOUT , 'trace' => true , 'encoding' => 'UTF-8' , 'attachment_type' => BeSimple\SoapCommon\Helper::ATTACHMENTS_TYPE_MTOM @@ -367,34 +374,37 @@ class ProcessoEletronicoRN extends InfraRN { public function consultarMotivosUrgencia() { $curl = curl_init($this->strComumXSD); - curl_setopt($curl, CURLOPT_URL, $this->strComumXSD); - curl_setopt($curl, CURLOPT_HEADER, 0); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); - curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); - curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($curl, CURLOPT_SSLCERT, $this->strLocalCert); - curl_setopt($curl, CURLOPT_SSLCERTPASSWD, $this->strLocalCertPassword); - $output = curl_exec($curl); - curl_close($curl); - - $dom = new DOMDocument; - $dom->loadXML($output); - - $xpath = new DOMXPath($dom); - - $rootNamespace = $dom->lookupNamespaceUri($dom->namespaceURI); - $xpath->registerNamespace('x', $rootNamespace); - $entries = $xpath->query('/x:schema/x:simpleType[@name="motivoDaUrgencia"]/x:restriction/x:enumeration'); - - $resultado = array(); - foreach ($entries as $entry) { - $valor = $entry->getAttribute('value'); - - $documentationNode = $xpath->query('x:annotation/x:documentation', $entry); - $descricao = $documentationNode->item(0)->nodeValue; - - $resultado[$valor] = utf8_decode($descricao); + + try{ + curl_setopt($curl, CURLOPT_URL, $this->strComumXSD); + curl_setopt($curl, CURLOPT_HEADER, 0); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl, CURLOPT_SSLCERT, $this->strLocalCert); + curl_setopt($curl, CURLOPT_SSLCERTPASSWD, $this->strLocalCertPassword); + $output = curl_exec($curl); + + $dom = new DOMDocument; + $dom->loadXML($output); + + $xpath = new DOMXPath($dom); + + $rootNamespace = $dom->lookupNamespaceUri($dom->namespaceURI); + $xpath->registerNamespace('x', $rootNamespace); + $entries = $xpath->query('/x:schema/x:simpleType[@name="motivoDaUrgencia"]/x:restriction/x:enumeration'); + + $resultado = array(); + foreach ($entries as $entry) { + $valor = $entry->getAttribute('value'); + $documentationNode = $xpath->query('x:annotation/x:documentation', $entry); + $descricao = $documentationNode->item(0)->nodeValue; + $resultado[$valor] = utf8_decode($descricao); + } + + } finally{ + curl_close($curl); } return $resultado; -- libgit2 0.21.2