Identificando Problemas – Congelamento e Conexões Presas – Parte 03

Introdução

No post anterior (https://siga0984.wordpress.com/2018/11/07/identificando-problemas-congelamento-e-conexoes-presas-parte-02), demos uma boa olhada sobre travamentos e congelamentos, desde a percepção do usuário, até algumas possíveis causas e alguns procedimentos de diagnóstico. Neste post, vou apresentar mais algumas possibilidades, e complementar alguns casos já vistos, e ver mais de perto o “temível” DEADLOCK 😀

Dicas para Todos os Casos

  1. Começamos procurando o processo no Protheus Monitor,e verificando se o total de instruções está sendo atualizado. Se não estiver sendo atualizado, o processo está esperando por “algo”.
  2. O processo tem conexão com o DBAccess? Verifique o que a conexão está fazendo. Se o DBAccess está “IDLE” faz algum tempo, seja lá o que o processo estiver esperando, não é um retorno do DBAccess. Elimine a conexão do DBAccess e espere ela sair do DBAccess monitor — isso pode demorar até 30 segundos, inclusive devido ao fato da aplicação não estar fazendo requisições para o DBAccess, ele somente verifica o flag de “derrubar a conexão” em intervalos de 30 segundos.
  3. O processo ainda está com o SmartClient aberto? Se tiver algum problema no SmartClient, e o server está esperando algo que deveria vir do SmartClient, derrubar o SmartClient também faria o processo terminar — porém com uma mensagem de erro de sincronismo, sem gerar log. Deixemos isso como ultima alternativa.
  4. Podemos também tentar derrubar o processo pelo Monitor do Protheus, mas lembre-se de não usar a opção “derrubar imediatamente”, senão o processo some do monitor, e você somente vai saber se ou quando ele saiu, depois de verificar o console.log do Application Server.
  5. Ao investigar ocorrências estranhas e com poucas pistas, procure obter mais informações, inclusive verifique os logs e configurações das aplicações envolvidas — DBAccess, LockServer (linux), License Server, Protheus Master, Slave(s), etc. — principalmente verifique se nestes serviços não está acontecendo algum ACCESS VIOLATION e FAILURE ON THREAD DELETE. Depois de ocorrências desta natureza, o comportamento da aplicação é imprevisível — mas normalmente os efeitos mais comuns são: Recursos bloqueados ou em uso por um processo que não está mais no Monitor, crescimento do uso da memória ao longo do tempo, inclusive congelamentos.

NÃO ACHEI … E AGORA ?

Beleza, você já olhou com uma lupa e não achou onde travou, ou pior, cada hora trava em um lugar diferente, só acontece na produção, ninguém reproduz no ambiente de desenvolvimento ou na homologação …

Abra um chamado na TOTVS, forneça os detalhes pertinentes, o analista de suporte pode pedir mais algumas informações, e se mesmo assim não for descoberto a causa ou o que está acontecendo, ainda assim é possível usar uma build Debug ou RWD (Release com informações de Debug) do Application Server, fornecida para a análise desta ocorrência, junto com um procedimento para gerar um “Core Dump” manualmente do Protheus Server, ou da aplicação em questão — no momento em que o travamento for reproduzido.

Através de um “Core Dump” gerado nestas condições, o time de Tecnologia consegue abrir este arquivo para análise, e determinar onde e o que cada processo dentro do servidor de aplicação estava fazendo no momento que o Dump foi gerado. Isso ajuda muito no diagnóstico, quando os demais procedimentos não deram resultados satisfatórios.

Outros Casos

Lembrando o caso clássico de “Impressão no Servidor” usando um Driver de geração de PDF, rodando o Protheus como serviço do Windows … O processo atual simplesmente TRAVA dentro do servidor. Este caso está bem detalhado no primeiro post — https://siga0984.wordpress.com/2015/08/01/identificando-problemas-memoria-no-advpl-parte-01/ — vale a pena dar uma lida nele, pois além de travar ele mantém vários recursos ocupados e abertos, como a conexão com o DBAccess , License Server, c-Tree, etc.

Existe também a possibilidade de haver algum erro de lógica ou falha de tratamento de eventos ou um estado de interface não previsto, onde o Loop ou o Travamento pode estar dentro do Application Server, ou mesmo dentro do SmartClient, disparados por alguma condição particular. São erros mais difíceis de serem diagnosticados, principalmente quando não existe — ou ninguém sabe como faz — uma receita de bolo para fazer o problema “aparecer” e ser reproduzido. Reproduzir bug em cativeiro é “de rosca”… Não tem como fugir das etapas do processo investigativo, e se nada deu certo, quando a ocorrência chegar até esta camada, cada caso é estudado individualmente no atendimento, onde outras medidas podem ser adotadas, desde uma build Debug, até uma build com uma instrumentação específica para levantar mais informações sobre a ocorrência pode ser fornecida para o cliente no ambiente em questão.

Outros tipos de Loop Infinito – O DEADLOCK

Esse é um dos tipos de ocorrência que dá mais trabalho de investigar, e seus efeitos são desastrosos … A aplicação AdvPL realiza as alterações de registro na base de dados obrigatoriamente solicitando um Lock de Registro, tratado pelo DBAccess. No ERP, usamos a função RecLock(), do FrameWork AdvPL, que possui um tratamento de retry para a obtenção do bloqueio.

Porém, uma vez que uma determinada aplicação esteja em JOB — Como um Scheduler ou um WebService, por default este retry é reiniciado em caso de falha. Caso dois processos diferentes tenham obtido cada um um determinado lock, e no momento atual um processo tenta obter o lock do registro que está com o outro processo, e vice-versa, temos um DEADLOCK na aplicação AdvPL.

Neste caso, se os dois programas estão em JOB — sem interface — ambos ficam tentando pegar cada um o lock que está com o outro processo, e como nenhum deles vai “desistir”, ambos ficam em loop até que um deles seja identificado e derrubado — pelo Monitor do Protheus ou do DBAccess.

Identificando os processos envolvidos

Normalmente dois ou mais processos entram em loop, fazendo várias tentativas de bloqueio de registro, e ninguém sai do lugar. Nestes casos, como eu não sei o que está acontecendo, uma das alternativas é verificar no DBAccess os processos com transação aberta a muito tempo — existe uma coluna nova para indicar isso — e então, usando o DBAccess Monitor, fazemos um TRACE de alguns segundos da conexão, para ver se ela está tentando pegar um lock e não está conseguindo. Depois de saber a tabela e registro envolvidos, você pode procurar quem é o dono do lock no Monitor de Locks do DBAccess, e ver o que esta conexão esta fazendo. Se ela também está tentando pegar outro lock, isso pode indicar um cenário de deadlock, onde basta chutar um dos processos para que o outro tenha a chance de ser finalizado.

WebServices e DEADLOCKs

Os WebServices do Protheus possuem uma configuração especial para fazer com que o retry para obter o lock seja executado apenas por um período de tempo determinado, e em caso de falha, o JOB do WEBSERVICE é encerrado com uma ocorrência de error.log, indicando que não foi possível obter o bloqueio de um determinado registro de uma tabela, inclusive fornecendo detalhes de qual era o processo que estava “segurando” este lock. A configuração chama-se ABENDLOCK=1, definida na seção de configuração das WORKING THREADS dos WEBSERVICES. De qualquer modo, a partir de Dezembro de 2017, esta configuração foi habilitada por DEFAULT nos WebServices, vide a nota de release da TDN.

DBAccess e DEADLOCKs

Devido a dificuldade de identificar os processos e registros envolvidos em uma ocorrência de DEADLOCK, seria muito interessante se o próprio DBAccess conseguisse identificar uma situação como essa, e avisar a um dos programas envolvidos que ele está envolvido em um DEADLOCK com um ou mais processos, onde a aplicação pode tratar a mensagem do DBAccess e finalizar-se automaticamente, gerando o log de erro correspondente e soltando os bloqueios obtidos, ou deixar que o DBAccess finalize uma das conexões automaticamente, para que as outras tenham chance de terminar.

Conclusão

Por hora, deixo as conclusões com vocês, eu apenas vou concluir este POST 🙂

Agradeço a todos novamente pela audiência, e desejo a todos TERABYTES de SUCESSO 😀

 

 

Identificando Problemas – Congelamento e Conexões Presas – Parte 02

Introdução

No primeiro post sobre identificação de problemas — Identificando Problemas  – Memória no AdvPL – Parte 01 — falamos sobre uso de memória e Leaks de memória. Hoje, vamos obter mais detalhes sobre travamentos, congelamentos, conexões e licenças “presas”, e ocorrências desta natureza.

IGH, TRAVOU…

Bem, um operador do ERP executa uma rotina ou sub-rotina qualquer, normalmente através do SmartClient, certo? Por sua vez, o SmartClient em si é uma aplicação em C++ que, em poucas palavras, foi feita para desenhar os componentes que a aplicação AdvPL criou dentro de uma caixa de diálogo ou Janela, e uma vez que a janela torna-se ativa — método ::Activate() do diálogo — os controles de entrada de dados e interação com a aplicação estão do lado do cliente, e o servidor aguarda pelo disparo de ações a partir dos componentes de tela, como clicar em um botão ou preencher um campo com dados.

Já o Protheus Server, executando um programa AdvPL, ao receber uma ação do SmartClient, executa o bloco de código correspondente a ação, que pode chamar rotinas e sub-rotinas, interagir com a interface atual, e até mesmo montar uma nova caixa de dialogo sobre a interface atual e torná-la ativa.

Do lado do usuário, no SmartClient, a percepção do usuário de “travamento” ou “congelamento” normalmente é percebida como “eu apertei um botão, que deveria fazer X, e nada aconteceu, e eu não consigo clicar ou fazer mais nada”.

Onde, quando, como e o quê travou ?

A resposta de cada uma destas perguntas leva para a próxima pergunta. Onde travou, a informação de qual botão em qual tela que foi apertado e percebido o travamento. Quando, é a informação sobre a periodicidade que isso ocorre. Sempre trava ao apertar este botão? Se não trava sempre, como faz para ele travar? Somente trava quando um campo da tela estava com o valor Y? Ou é uma ocorrência esporádica?  O botão funciona o dia inteiro, e de repente trava…

A resposta da última pergunta é a questão de um milhão …  risos … existem muitas coisas que podem ter acontecido. Vamos enumerar aqui boa parte das possibilidades.

Loop Infinito

Aquele botão dispara uma rotina, com um determinado conjunto de parâmetros, e existe um erro de lógica na rotina, onde uma parte do código entra em loop, realizando um determinado processamento e esperando por uma determinada condição para finalizar o loop. Por exemplo, a rotina abriu uma Query, e está lendo campos da Query e acrescentando um valor em uma variável, até que a Query termine, mas dentro do laço o programador esqueceu de colocar um DBSkip() — ou fez esta operação sem querer em um outro ALIAS, ao invés de fazer na QUERY —  ou ainda um laço FOR … NEXT que usou uma variável N, que inadvertidamente foi alterada dentro do loop, para um outro valor menor, fazendo com que o laço não termine.

Nestes casos, ao abrir o Monitor de Processos do Protheus, e localizar o usuário, a coluna que indica o número total de instruções está sempre crescendo, normalmente a CPU fica mais alta no serviço do Protheus que está executando este processo, e o número de instruções por segundo mostrado no Monitor do Protheus também é alto.

Esse é um caso simples de descobrir onde está o problema, basta finalizar o processo pelo Monitor do Protheus, preferencialmente sem marcar a opção “derrubar imediatamente”. A aplicação AdvPL em loop vai perceber entre uma instrução e outra que ela foi marcada para ser finalizada — é isso que o Monitor do Protheus faz quando você manda finalizar um processo. No momento que a aplicação perceber isso, ela finaliza o processo, com uma ocorrência de erro “Process terminated by Administrator” ou algo assim, gerando uma ocorrência de erro com o stack ou pilha de chamada de funções, para mostrar onde foi que o Protheus “percebeu” que o processo foi marcado para ser finalizado.

Nesta situação, quando o Programa AdvPL está em LOOP e não está interagindo com a Interface, a cada 10 segundos o Protheus Server verifica se o SmartClient ainda está lá, aguardando pela resposta. Caso o Server perceba que o SmartCient caiu, ou a conexão de rede foi interrompida, ele finaliza o processo atual com a ocorrência de erro fatal em AdvPL “Remote Connection BROKEN”.

Latência alta de rede entre Protheus e SmartClient

Normalmente quando isso acontece, o processo dá a impressão de ter “travado”, porém em alguns segundos a tela que deveria aparecer simplesmente “aparece”. Imagine que o programa em AdvPL está desenhando uma nova caixa de diálogo, com muitos componentes, e durante a montagem da tela o programa pede ao SmartClient coordenadas de tela e informações sobre as dimensões dos componentes em fase de montagem. Uma latência de rede momentânea de 500 ms (milissegundos) pode fazer uma tela que, durante sua montagem, faça 10 requisições ao SmartClient, demorar quase 5 segundos para ser finalizada. Num caso como esse, o monitor do Protheus mostra um numero de instruções por segundo perto de zero, e o número de instruções total sobe bem devagar.

Instrução em execução no Banco de Dados

Imaginem o cenário, onde a aplicação AdvPL monta uma Query dinâmica, porém devido a um erro de lógica ou validação de parâmetros, a Query fez um produto cartesiano da tabela, ou um INNER JOIN sem WHERE …. ou uma daquelas queries rebuscadas, que fazem múltiplas buscas em uma tabela enorme, usando um ou mais campos que não possuem um índice para o Banco de Dados otimizar a busca, e o Banco de Dados precisa fazer FULL SCAN (ler a tabela inteira) para retornar os dados solicitados.

Quando a aplicação AdvPL submeter a Query ao DBAccess, e este por sua vez submeter a query ao Banco de Dados, o AdvPL espera o retorno da API do DBAccess, e o DBAccess por sua vez está esperando o Banco de Dados. Isso também pode acontecer, por exemplo, com a chamada de uma Stored Procedure de processamento, quando parametrizada para rodar sobre grandes volumes de dados, ou mesmo falta de optimização de índices no banco para roda as queries submetidas por dentro da Stored Procedure.

No monitor do Protheus, será mostrado que o número total de instruções não aumenta, e o número de instruções por segundo permanece em 0 (zero). Ao abrir o Monitor do DBAccess — última versão do Portal — nós temos duas novas colunas de monitoramento muito úteis para casos como esse: A coluna “IDLE” e a “RUNNING”. A coluna IDLE indica a quantos segundos esta conexão do DBAccess não recebeu nenhum pedido de dados do programa AdvPL que a abriu, e a coluna “RUNNING” mostra naquele instante se e qual a rotina do DBAccess que está sendo executada.

Com isso, se a Query está ainda rodado dendo do Banco de Dados, a coluna RUNNING deve mostrar a operação OP_QUERY. No caso de uma Stored Procedure, se eu não me engano é a operação OP_SPEXEC.

Uma das colunas do DBACCESS Monitor — se eu não me engano DBSID ou apenas SID — mostra um identificador da conexão do DBAccess junto ao Banco de Dados. Esse identificador permite o DBA ou o Administrador do Ambiente a abrir uma conexão diretamente com o Banco de Dados, usando uma ferramenta de monitoramento nativa do Banco, e associar uma conexão mostrada pelo Monitor do SGDB com uma conexão do DBAccess.

Em um caso como esse, não adianta tentar matar a conexão do DBAccess com o Banco de Dados pelo Monitor do DBAccess, vai cair no mesmo problema do Protheus: Enquanto o DBAccess não receber um retorno da API do Banco, nada acontece … Mesma coisa derrubar com o Protheus Monitor … mesmo que você use a opção “derrubar imediatamente”, o SmartClient pode ser finalizado na hora, ao perceber que a conexão dele com o Protheus foi encerrada do lado do servidor, mas o programa AdvPL ainda vai estar esperando um retorno do DBAccess.

Neste caso, a última alternativa — antes de derrubar o serviço do Protheus e do DBAccess — é pegar o número ou identificador da conexão com o Banco de Dados, e usando uma ferramenta administrativa do Banco de Dados, pedir para o SGDB encerrar esse processo. Assim que isso foi feito, o SGDB retorna um erro de “Processo Interrompido” para o DBAccess, que por sua vez retorna este erro ao programa AdvPL.

Instrução em execução no SmartCient

Ao clicar naquele botão, o programa AdvPL em execução no Protheus Server pediu para o SmartClient abrir, por exemplo, uma URL a partir da estação onde o SmartClient está sedo executado — função HTTPCGet() — e o endereço solicitado está congestionado de requisições e coloca a sua na fila … Esta função tem um time-out de 120 segundos por default, o que pode “brecar o sistema” onde por 2 minutos.

Em um caso como esse ou similar, onde o Application Server está esperando por alguma coisa do SmartClient, quando você derruba (chuta) o SmartClient, finalizando o processo, o Protheus Server identifica que a interface de rede entre eles foi interrompida, e finaliza o programa AdvPL em execução com aquela ocorrência “Erro de Sincronismo”.

Conexão parcialmente fechada

Este é um cenário bem ingrato … você abriu um SmartClient, e iniciou aquele relatório que demora pelo menos uma hora … Você manda imprimir no SPOOL, e vai tomar um café. O programa que emite o relatório atualiza de vez em quando uma régua de processamento na tela do SmartClient. Passou uma hora, e a régua nem se mexeu … Você vai no Monitor do Protheus … e não encontra esse usuário. Vai no DBAccess, e também não acha nada … mas o SmartClient está ali, aberto, e a régua parada … e você não consegue nem clicar no botão cancelar … o que aconteceu?

Um caso como esse pode indicar uma conexão de rede parcialmente fechada. Durante o processamento do relatório, houve uma falha na rede, porém o encerramento da conexão TCP somente foi percebido pelo Protheus Server, quando ele foi atualizar a régua. Já o SmartClient, que fica somente esperando o Protheus pedir alguma coisa quando o controle de interface não está com ele, e existe um processamento no Protheus Server em andamento, caso a conexão TCP do lado do SmartClient não acuse o erro ou fechamento da outra ponta, o SmartClient fica esperando pra sempre um retorno que nunca vai chegar.

Cenários como esse podem ser contornados com a utilização de um aplicativo fornecido pela TOTVS para o Protheus Server chamado BROKER — ele serve de ponte e proxy reverso para as conexões do SmartClient para o(s) Protheus Server, inclusive para fazer balanceamento de carga. Ele entra na frente das conexões, tanto no SmartClient como no Application Server, e mantem uma conversa “constante” entre as pontas, sendo capaz de detectar com maior precisão quando uma das pontas foi desconectada,  e inclusive pode conseguir reconectar uma conexão encerrada devido a eventual e momentânea instabilidade na rede, sem que nenhuma das pontas (APPServer ou SmartClient) perceba o que aconteceu.

Ocorrências críticas

Um cenário difícil, mas plausível. Uma aplicação AdvPL reproduz um erro no Protheus Server, mostra uma caixa de diálogo com detalhes do erro no SmartClient, e quando você clica no “Ok” para fechar a janela, ela fecha. Então, você vai no DBAccess, e a conexão está lá .. e no license Server também … mas no Monitor do Protheus, esse usuário “sumiu”, e você tem certeza que ninguém usou aquele recurso de “derrubar imediatamente” aquele processo. O que pode ter acontecido?

Ao consultar o log de console do Protheus Server (console.log), você encontra o registro do Erro Advpl, logo depois uma mensagem parecida com “Critical Error”, seguida por “Falha no Delete da Thread” ou similar. Isto significa que, durante a descarga do ambiente, programas e recursos, ocorreu um erro critico na aplicação AdvPL, como pr exemplo invasão de memória, justamente enquanto aquele contexto de execução estava sendo limpo — executando os destrutores internos do Protheus. Se isso acontecer, uma parte dos recursos que seu processo continuam ativos neste processo mas o processo parcialmente não existe, somente o próprio processo consegue finalizar-se de modo elegante. Então, o processo some da lista de monitoramento, mas cai na malha dos processos com falha no destrutor.

Ocorrências desta natureza devem ser reportadas para a TOTVS, para a melhoria contínua do software. Normalmente a utilização de uma build DEBUG nestes casos ajuda a gerar um arquivo de CORE DUMP no momento que uma ocorrência crítica aconteça, gerando postas sólidas do que pode ter acontecido.

Conclusão

Espeto que estas poucas linhas ajudem aos analistas que procuram fantasmas nos ambientes do Protheus pelo mundo afora !!

Desejo novamente a todos TERABYTES DE SUCESSO !!! 

 

Protheus como Servidor de FTP

Introdução

Quando eu comentei um pouco sobre as capacidades do Servidor de Aplicação Protheus Server, em um post mais antigo, eu mencionei que ele não apenas servia a conexões do SmartClient para rodar aplicações AdvPL, mas também que ele poderia ser um servidor de HTTP, com páginas estáticas e dinâmicas — usando AdvPL ASP — bem como TELNET e FTP. No post de hoje, vamos explorar o que a gente puder sobre como usar um Protheus Server como servidor de FTP.

Configuração Mínima

Imagine que você quer usar um Protheus Server como um FTP Server, com acesso anônimo — sem criticar usuário e senha — e apenas disponibilizar uma estrutura de pastas para Download. Neste caso, a configuração mínima para este serviço, seria acrescentar no arquivo de configuração do Protheus (appserver.ini) a seção [FTP], com as seguinte chaves:

[ftp]
Enable=1
Port=21
Path=c:\Protheus12LG\EnvLight\ftp
CanAcceptAnonymous=1

Especificamos a porta padrão (21), o acesso anônimo habilitado, e o path raiz do FTP, a partir do qual as conexões terão acesso de Download. Dentro da pasta configurada em “path”, eu coloquei um arquivo chamado leiame.txt, vamos ver este acesso através de um cliente FTP nativo do Windows, usando o comando “ftp” em linha de comando.

C:\Users\siga0>ftp -A localhost
Connected to NOTE-JULIOW-SSD.
220 Connected to FTP server
331 Anonymous access allowed
502 Command not implemented
331 Anonymous access allowed, send email name as PASS
220 Logon successful
230 Welcome to Application Server FTP!
Anonymous login succeeded for siga0@NOTE-JULIOW-SSD
ftp> dir
250 PORT command successful
150 Opening ASCII mode data connection
-r-xr-x--- 1 owner group 39 Nov 04 20:10 leiame.txt
226 Transfer Complete
ftp: 74 bytes received in 0.00Seconds 37.00Kbytes/sec.
ftp> ls
250 PORT command successful
150 Opening ASCII mode data connection
leiame.txt
226 Transfer Complete
ftp: 15 bytes received in 0.00Seconds 15.00Kbytes/sec.
ftp>

Através do parâmetro “-A” na linha de comando, informamos ao cliente FTP que o Login deverá ser anônimo. Caso este parâmetro não seja especificado, você deve entrar manualmente com o usuário “anonymous“. Uma senha deve ser informada, mas não será validada — pode ser qualquer coisa, inclusive “anonymous”.

Após feito o login, executamos os comandos “ls” e “dir” para recuperar a lista de arquivos e pastas disponíveis para download. Vamos então fazer o download do arquivo “leiame.txt”:

ftp> get leiame.txt
250 PORT command successful
150 RETR command started
226 Transfer Complete
ftp: 39 bytes received in 0.00Seconds 39000.00Kbytes/sec.
ftp>

De dentro do FTP Client do Windows, podemos executar um comando do sistema operacional, prefixando ele com o sinal de exclamação. Por exemplo, para verificarmos  o conteúdo do arquivo na pasta local após o Download, vamos executar o comando “type”.

ftp> !type leiame.txt
Exemplo de Configuraτπo Mφnima de FTP
ftp>

No caso, o texto do arquivo justamente é “Exemplo de Configuração Mínima de FTP”. Porém, como a página de código do Prompt de Comando está com o CodePage 437 (CodePage original do IBM-PC, também conhecido por OEM-US, CP437 ou DOS Latin US), a acentuação é mostrada com outros caracteres. Para ver o arquivo da forma correta, ele pode ser aberto pelo NOTEPAD ou qualquer outro editor de textos, OU você deve digitar no Prompt de Comando a instrução abaixo, antes de abrir o cliente FTP:

mode con cp select=1252

Com isso, o seu Prompt de Comando vai usar o CodePage do Windows, CP1252, que também é o CodePage usado pelo Protheus. Para ver a lista de instruções implementadas na camada interna do FTP Server, use o comando remotehelp

ftp> remotehelp
214-The following commands are implemented
USER PASS ACCT QUIT PORT RETR
STOR DELE RNFR PWD CWD CDUP
MKD RMD NOOP TYPE MODE STRU
LIST HELP
214 HELP command successful
ftp>

Caso você tente fazer um upload no FTP nesta conexão, a operação será negada.

ftp> put upload.txt
250 PORT command successful
550 Access is denied
ftp>

Usando outros clientes FTP

Normalmente basta desligar o “Passive Mode” na configuração do programa que você usa como Cliente de FTP (SCP, WINSCP, etc.) que a conexão e operações são realizadas sem maiores problemas.

Implementando mais controles

Na configuração mínima, o FTP está totalmente aberto para download de qualquer arquivo colocado a partir da pasta configurada na chave PATH, para qualquer cliente que conecte usando a identificação “anonymous” — ou seja, sem autenticação alguma. No máximo, usando por exemplo um recurso externo, como um Firewall, você pode permitir por exemplo apenas receber conexões FTP na porta 21 a partir de um ou mais endereços de rede, e apenas isso.

Para atender a necessidade de permitir ou restringir operações por usuário, existe a necessidade de desligar o acesso anônimo, configurar algumas chaves adicionais na seção [FTP], e criar algumas funções AdvPL no repositório para serem acionadas por estas chaves. Vamos direto para o exemplo completo:

[ftp]
Enable=1
Port=21
Path=c:\Protheus12LG\EnvLight\ftp
RPCEnv=envlight
CheckPassword=U_FTPPASS
GetUserPath=U_FTPPATH
CheckUserOper=U_FTPOPER

Primeiramente, removemos o acesso anônimo. Então, criamos uma chave chamada RPCENV, onde colocamos o nome  do environment (ambiente) existente neste Protheus Server, responsável por executar as funções AdvPL que serão colocadas para validar algumas operações do FTP.

Configuração CHECKPASSWORD

Quando um usuário conectar no FTP e informar o usuário e senha, será chamada a função U_FTPPASS(), que receberá como parâmetros o usuário e senha informados pelo cliente de FTP. Se esta função retornar .T., o Protheus Server responde ao cliente de FTP que o login foi aceito, caso contrário responde uma mensagem de erro e nega o acesso. Vejamos o exemplo abaixo:

User Function FTPPass(cUser,cPass)
cUser := lower(cUser)
if ( cUser == "root" )
  if( cPass == "root" )
    Return .T.
  Endif
Endif
Return .F. 

Neste exemplo, permitimos apenas um usuário chamado “root”, com a senha “manager”  a entrar no FTP.

Configuração GETUSERPATH

Imagine que, eu quero fornecer, por exemplo, uma pasta raiz de FTP diferenciada para alguns usuários. Para isso, eu crio uma função AdvPL — no nosso exemplo, USER FUNCTION FTPPATH(), que recebe como parâmetros o usuário e senha informados no login. A função deve retornar um PATH completo no servidor onde está sendo executado o Protheus Server, e esta pasta será o diretório raiz de FTP. Vamos ao exemplo:

User Function FTPPath(cUser,cPass)
cUser := lower(cUser)
If cUser == "siga0984"
  return "C:\Protheus12LG\ftp"
Endif
Return "C:\Protheus12LG\ftp\anonymous"

Neste caso, quando o usuário de FTP for “siga0984“, ele têm acesso à pasta raiz do FTP, quando qualquer outro usuário somente terá acesso a partir da pasta “anonymous”.

Configuração CHECKUSEROPER

Caso você queira permitir UPLOAD de arquivos no FTP, ou outras operações que modifiquem conteúdo, como apagar arquivo, criar ou apagar uma pasta, é necessário implementar uma função AdvPL para ser chamada pelo Protheus Server para autorizar estas operações, usando a configuração CheckUserOper — no nosso exemplo, vamos implementar a função U_FTPOPER(). Ela recebe três parâmetros: O usuário de login no FTP Server, a senha utilizada, e o comando enviado pelo Cliente do FTP.

Apenas alguns comandos são desviados para esta função, por exemplo STOR <arquivo>, DELE <arquivo>, MKD <pasta>,  RMD <pasta>, e dois comandos não implementados para renomear arquivo (RNFR e RNTO).

  • STOR = Upload de arquivo
  • DELE = Apagar arquivo
  • MKD = Criar pasta 
  • RMD = Remover pasta
  • RNFR <arquivo1> e RNTO <arquivo2> — Renomar arquivo1 para arquivo2

Caso a função AdvPL retorne .T., a operação é autorizada. Caso contrário, negada. Vamos ao nosso exemplo:

User Function FTPOPER(cUser,cPass,cOper)
Local cCmd
cUser := lower(cUser)
If cUser == 'root'
  cCmd := left(cOper,4)
  If cCmd $ "STOR,DELE"
    Return .T.
  Endif
Endif
Return .F.

No exemplo acima, permitimos apenas ao usuário “root” a possibilidade de fazer upload ou mesmo de apagar um arquivo remotamente.

Resultados dos Testes

Os testes realizados mostraram que alguns clientes de FTP, por exemplo o WINSCP, usou uma sintaxe para a troca de pasta (comando CWD) que o FTP Server do Protheus não entendeu, mas funcionou adequadamente com o cliente FTP nativo do Windows em linha de comando, e um cliente de FTP do Altap(r) Salamander.

Mesmo com as implementações em AdvPL, o objetivo de ter um servidor nativo de FTP no servidor Protheus é atender a necessidade de integrações entre sistemas, normalmente em ambientes restritos — ou fechados. Ele não oferece logs de utilização nativos, não permite interceptar outros comandos para implementar por exemplo restrição de acesso de usuário para uma pasta ou arquivo, etc.

Devido a questões ligadas a implementação do FTP em múltiplas plataformas, é recomendado usar os nomes de arquivos sem espaços em branco, sem acentuação, e com letras minúsculas, e utilizar sub-pastas se e somente se realmente necessário. Qualquer demanda maior, que exija mais controles, como um FTP publicado na Internet para clientes e parceiros ter acesso a múltiplos arquivos, eu pessoalmente recomendo a utilização de uma aplicação especializada em ser Servidor de FTP, que vai lhe oferecer nativamente muito mais controles do que o Protheus Server como FTP Server.

Conclusão

Para cada tamanho de problema, existe uma solução adequada. O Protheus como servidor de FTP não foi criado para competir com um FTP Server de mercado, mas apenas para ter uma alternativa simples e nativa para integração entre sistemas, onde não são necessários níveis muito avançados de controle. Porém, para o que ele se propõe, ele dá conta do recado.

Em um próximo post, vamos explorar a classe client de FTP do Protheus Server —  chamada TFTPCLIENT() — para conectar e realizar operações de Cliente de FTP conectando-se em um FTP Server configurado também no Protheus.

Agradeço novamente a audiência, e desejo a todos TERABYTES DE SUCESSO !!!

Referências

 

 

Seu primeiro Webservice REST no ERP Protheus

Desmistificando o MVC no AdvPL

  – O que é REST?

A web é amplamente utilizada e reconhecida principalmente por sua arquitetura robusta, escalável e tolerante a falhas. Quem sustenta esses fatores e lhe dá todo este poder é o protocolo HTTP (o protocolo HTTP é utilizado, em regra, quando se deseja evitar que a informação transmitida entre o cliente e o servidor seja visualizada por terceiros, como, por exemplo, no caso de compras online.). Atualmente, muitas vezes necessitamos integrar aplicações em ambientes totalmente diferentes e os WebServices são uma das maneiras mais comuns e fáceis de integrar os diferentes sistemas. Este post mostrará um pouco de um modelo de WebService chamado REST.

Representational State Transfer ou somente REST, é cada vez mais usado como alternativa ao “já antigo” SOAP onde que a principal crítica a esta é a burocracia, algo que REST possui em uma escala muito menor.
REST é baseado no design do protocolo HTTP, que já possui diversos mecanismos…

Ver o post original 1.454 mais palavras

Protheus no Linux – Parte 04

Introdução

No post anterior, preparamos um banco MySQL 5.5 e a UnixODBC na VM do Ubuntu 64. Agora, vamos instalar um DBAccess 64 bits no Linux e configurá-lo para usar o MySQL.

Instalação

Basicamente, precisamos de um arquivo contendo a distribuição 64 bits Linux do DBAccess. No exemplo de instalação, usei a versão disponível no portal da Totvs ( 16-03-15-DBACCESS_LINUX64_20141119.TAR.GZ )

Após subir a VM, usamos um WINSCP para criar dentro na estrutura de diretórios proposta para a aplicação (Post – Parte 01), uma pasta para a build do DBAccess que vamos instalar. A partir da pasta /totvs, criamos a pasta /dbaccess, e dentro dela a pasta 20141119 (referente a build em uso), e copiamos o arquivo mencionado para ela.

Usando um Putty, acessamos a VM pelo terminal e descompactamos o arquivo, usando os comandos:

cd /totvs/dbaccess/20141119/
tar zxvf 16-03-15-DBACCESS_LINUX64_20141119.TAR.GZ

Feito isso, vamos subir o DBAccess em modo “console”. A distribuição Linux 64 do DBAccess possui 2 executáveis : dbaccess64opt (Build Release) e dbaccess64dbg (Build Debug). A pasta “multi” significa que a versão de DBAccess dentro dela foi feita para conectar com múltiplos bancos de dados. Para subir esta versão em modo console, usamos os seguintes comandos :

cd multi
export LD_LIBRARY_PATH=./
./dbaccess64opt

DBAccess Linux64

Configurar conexão do MySQL no DBAccess

Você pode utilizar um DBAccess Monitor instalado no Windows, por exemplo, para conectar no DBAccess Server da máquina Linux, e proceder com a configuração da conexão com o MySQL.

Ao entrar na aba MySQL, e clicar em “Novo”, crie uma configuração com o mesmo nome de DSN no Linux que criamos no post anterior – no caso do exemplo, envp11mysql. Preencha os campos “usuário” e “senha” com o usuário e senha que criamos no MySQL durante a criação do banco de dados envp11mysql.

Testar a conexão

Usando o próprio DBAccess Monitor, na pasta “Assistentes”, usamos o recurso de Validação de Conexão, informamos o banco MySQL, depois informamos o nome da conexão (envp11mysql), e devemos receber a mensagem abaixo:

DBAccess Falha Conexão

Para ver o que houve, vamos olhar o console do DBAccess no terminal do Linux. Deve haver uma mensagem de erro parecida com a mensagem abaixo:

Begin TopClient Thread (3256297216,192.168.1.63,MYSQL/envp11mysql,DBMonitor,julio.wittwer,NOTE-AUTOMAN)
BEGINLOG]
Connection [MYSQL/envp11mysql] could not load database client library [libmyodbc3_r.so]
[ENDLOG]
[BEGINLOG]
libmyodbc3_r.so: cannot open shared object file: No such file or directory
[ENDLOG]
Exit TopClient Thread (3256297216) [ERROR -35]

O DBAccess está procurando uma lib client antiga do MySQL, para tentar conectar com ele, e não vai encontrá-la. Após instalar o DBAccess e configurar a conexão, precisamos editar o arquivo dbaccess.ini, e informar ao DBAccess que ele deve carregar a UnixODBC para acessar o MySQL. Para isso, usamos a chave clientlibrary na seção [MYSQL].

Primeiro, finalize o DBACcess, usando Control+C no console. Agora, vamos localizar o driver da UnixODBC. Normalmente ele está em alguma pasta da lib gnu Linux, em /usr/lib. Para verificar onde exatamente ela está, usamos o comando abaixo:

find /usr/lib -name 'libodbc.so*'

No meu ambiente, foram localizados os seguintes arquivos:

/usr/lib/x86_64-linux-gnu/libodbc.so.1.0.0
/usr/lib/x86_64-linux-gnu/libodbc.so.1

No dbaccess.ini, dentro da seção [mysql], colocamos a chave abaixo:

clientlibrary=/usr/lib/x86_64-linux-gnu/libodbc.so.1

DBACcess Ini

Após salvar o arquivo e subir o DBAccess novamente, vamos testar a conexão usando o assistente do DBAccess Monitor. E, se tudo estiver de acordo, devemos visualizar a mensagem abaixo:

DBAccess Conexão Ok

Subindo o DBAccess em modo “daemon”

Haja visto que o Banco de Dados MYSQL já está no ar, e o DBAccess está funcionando, podemos subir ele em modo “daemon”, sem deixar ele preso ao terminal. Para isso, usando o próprio terminal atual, finalizamos o DBAccess em modo console usando Control+C, e subimos ele em modo “daemon” usando o seguinte comando:

nohup ./dbaccess64opt -daemon

Para verificar se o processo do DBAccess está realmente no ar, podemos rodar uma instrução do Linux para listar os processos, filtrando o resultado por aqueles que contém a string “dbaccess”, usando o comando abaixo:

ps -ef | grep dbaccess

O retorno deste comando deve ser algo parecido com:

siga0984   1568      1  0 08:54 pts/0    00:00:00 ./dbaccess64opt daemon
siga0984   1591   1410  0 08:58 pts/0    00:00:00 grep --color=auto dbaccess

O que nos interessa é a primeira linha, pois informa o número do processo pelo qual o sistema operacional subiu o DBAccess64 – no nosso exemplo, 1568.

Para baixar o processo do DBAccess de forma controlada, usamos um terminal do Linux, e usamos o comando kill, informando como parâmetro o número do processo a ser finalizado. Por exemplo:

kill 1568

Para verificar se o processo está no ar, podemos usar novamente o comando “ps”. As mesmas regras se aplicam ao processo do Protheus Server. Ele pode ser colocado em modo “daemon” usando a mesma sintaxe, e verificado da mesma forma, usando o comando “ps”.

Conclusão

Com o DBAccess instalado e funcionando na própria máquina Linux, basta editar o arquivo appserver.ini da instalação do Protheus Server feita no segundo post desta sequência, para apontar para o banco MYSQL em localhost, para o alias “envp11mysql”, e agora temos um ambiente mínimo e operacional do Protheus 11 em uma máquina Linux 64.

Entre uma distribuição e outra de Linux, pode haver mudança nos comandos, a configuração de alguns itens pode ser manual e dar um pouco mais de trabalho, algumas distribuições vem com Firewall habilitado e requer mais passos de setup para abrir as exceções, alguns arquivos podem estar em outro lugar, ou ter um nome diferenciado, o gerenciador de pacotes é diferente, e assim por diante.

Estes primeiros posts foram apenas para “abrir o apetite”, temos muito a abordar ainda sobre isso nos próximos posts deste assunto 😀

Enquanto isso, agradeço novamente a audiência, e desejo a todos TERABYTES de SUCESSO 😉

 

Protheus no Linux – Parte 03

Introdução

No post anterior, instalamos na VM Ubuntu um Protheus Server, instância única, usando um c-Tree Server DLL (ou BoundServer). Agora, vamos instalar um banco de dados MYSQL e a UnixODBC nesta mesma VM.

Instalando

Após iniciar a VM do Ubuntu Linux — montada no primeiro post –, executamos os comandos abaixo, para instalar o MYSQL e a UNIXODBC, respectivamente:

sudo apt-get install mysql-server mysql-client
sudo apt-get install libmyodbc unixodbc-bin unixodbc

Com estes comandos, nesta versão do Sistema Operacional, o MySQL 5.5 será instalado. Durante a instalação, será perguntada uma senha do usuário “root” do MySQL. Insira uma senha e guarde-a, ela será necessária nas etapas posteriores.

Criando a base no MySQL

Após a instalação, o banco MYSQL já deve estar no ar, mas sem nenhuma base de dados. Utilize o comando “mysql” para acessar o interpretador de comandos do MySql, com a sintaxe abaixo:

mysql -u root -p

Uma vez dentro do interpretador de comandos do MySql, execute os comandos abaixo para criar a sua base de dados. Troque o conteúdo de ‘usuariodebanco’ para um nome de usuário que você queira criar no banco de dados para ter acesso a essa base. Você pode dar o mesmo nome do usuário que você criou para o sistema operacional. E, no lugar de ‘senha’, coloque a senha que você quer atribuir a este usuário, para ele acessar o Banco de Dados.

create database envp11mysql;
grant all on envp11mysql.* to 'usuariodebanco' identified by 'senha';

Mysql Create DB

Configurando a UnixODBC

Para não acessarmos diretamente a .so ( shared object library ) do banco de dados, vamos configurar a UnixODBC no Linux para o Mysql. Primeiro, vamos entrar em “root” mode no Linux, com o comando abaixo:

sudo su

Agora, vamos ver exatamente onde foram instaladas as libs ODBC do MySQL, usando o comando abaixo:

find / -name 'lib*odbc*.so'

O resultado esperado deve ser bem próximo de:

/usr/lib/x86_64-linux-gnu/odbc/libodbcdrvcfg2S.so
/usr/lib/x86_64-linux-gnu/odbc/libodbcnnS.so
/usr/lib/x86_64-linux-gnu/odbc/libodbcdrvcfg1S.so
/usr/lib/x86_64-linux-gnu/odbc/libodbctxtS.so
usr/lib/x86_64-linux-gnu/odbc/liboraodbcS.so
/usr/lib/x86_64-linux-gnu/odbc/libodbcmyS.so
/usr/lib/x86_64-linux-gnu/odbc/libmyodbc.so
/usr/lib/x86_64-linux-gnu/odbc/libodbcpsqlS.so
/usr/lib/x86_64-linux-gnu/odbc/liboplodbcS.so
/usr/lib/x86_64-linux-gnu/odbc/libodbcminiS.so

Os arquivos que nos interessam são os dois em destaque:

libmyodbc.so = MySQL Driver API 
libodbcmyS.so = MySQL Driver Setup

Agora, vamos criar a configuração de instalação da UnixODBC. Usando o editor de arquivos texto no Linux, crie o arquivo odbcinst.ini na pasta /etc/

sudo vi /etc/odbcinst.ini

O conteúdo do arquivo deve ser o seguinte:

[odbc_mysql]
Description     = ODBC for MySQL
Driver          = /usr/lib/x86_64-linux-gnu/odbc/libmyodbc.so
Setup           = /usr/lib/x86_64-linux-gnu/odbc/libodbcmyS.so
UsageCount      = 1

Agora, vamos ver a onde está a configuração de Sockets do MySQL, usando o comando abaixo:

mysqladmin -u root -p version

O resultado deve ser parecido com este aqui:

mysqladmin  Ver 8.42 Distrib 5.5.49, for debian-linux-gnu on x86_64
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Server version          5.5.49-0ubuntu0.14.04.1
Protocol version        10
Connection              Localhost via UNIX socket
UNIX socket             /var/run/mysqld/mysqld.sock
Uptime:                 23 min 17 sec


Threads: 1  Questions: 583  Slow queries: 0  Opens: 189  
Flush tables: 1  Open tables: 41  Queries per second avg: 0.417

O que nos interessa é a informação em negrito: O caminho do Unix Socket em uso pelo Banco de Dados. Agora, baseado no que já temos até agora, vamos criar a configuração de ODBC efetivamente, apontando para os drivers.

vi /etc/odbc.ini

Podemos partir do seguinte conteúdo:

[envp11mysql]
Description = DSN para Banco P11 no MySQL
Driver      = odbc_mysql
Server      = localhost
Port        = 3306
Socket      = /var/run/mysqld/mysqld.sock
Database    = envp11mysql
Option      = 3
ReadOnly    = No

Na prática, os nomes das seções nos arquivos de configuração somos nós que definimos. No arquivo odbcinst.ini, cada seção configura um driver de banco diferente. No arquivo odbc.ini, cada seção corresponde a uma entrada de DSN da Odbc, que usa um determinado driver.

Após criar e editar os arquivos, vamos efetivar o registro das informações na UnixODBC, inicialmente instalando o Driver que configuramos, usando o comando abaixo.

odbcinst -i -d -f /etc/odbcinst.ini

Agora, vamos instalar a nossa configuração de DSN como “System DSN”, usando o comando abaixo:

odbcinst -i -s -l -f /etc/odbc.ini

Agora, usando o comando abaixo, podemos consultar quais DSN de sistemas estão instaladas:

odbcinst -s -q

E, finalmente, podemos testar a conexão com o MySQL via UnixODBC, usando o comando abaixo, trocando “MYSQLUSER” pelo usuário que nós criamos para o banco envp11mysql , e “MYSQLUSERPASSWORD” trocando pela senha utilizada.

isql -v myodbc_mysql_dsn MYSQLUSER MYSQLUSERPASSWORD

O resultado esperado é :

 

+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL>

 

Para sair do interpretador de comandos SQL, use a instrução “quit”. Com isso, já temos o MySQL instalado, um banco criado, e a UnixODBC devidamente configurada.

Referências

“Kafee Talk – How to setup and configure MySQL with unixODBC under Ubuntu 14.04”. Disponível em <http://www.kaffeetalk.de/how-to-setup-and-configure-mysql-with-unixodbc-under-ubuntu-14-04/>. Acesso em 16 de Julho de 2016.

Conclusão

Sim, foi mais simples e mais rápido do que imaginávamos. E, com mais um ou dois passos, você configura o MySQL no Linux para aceitar conexões TCP remotas, e pode instalar uma ODBC no Windows, e usar o MYSQL no Linux — Basta editar o arquivo /etc/mysql/my.cnf , localizar a configuração bind-address, e trocar ela para 0.0.0.0 😉 Mas, o foco é usarmos o MySQL no Linux, com o DBAccess também no Linux. E esta etapa será abordada no próximo post dese assunto !!!

Agradeço a todos pela audiência, e lhes desejo TERABYTES DE SUCESSO 😀 

Protheus no Linux – Parte 02

Introdução

No post anterior, vimos um passo a passo da montagem de um ambiente mínimo de um servidor Linux, mais precisamente um Ubuntu Server 14 – 64 bits, conde já executamos algumas etapas de preparação para ele receber um Protheus Server. Neste post, vamos colocar um Protheus Server 11 64 bits nele !

Instalando o Protheus Server

Após iniciar sua VM, verificar o IP, e abrir um terminal ( Putty ), crie uma pasta a partir da pasta raiz do Linux, para armazenar seus ambientes e aplicações. No lugar de <usuario>, use o usuário que você criou na instalação do Linux.

sudo mkdir /totvs
sudo chown usuario /totvs
cd /totvs

Com estes comandos, criamos a pasta, e damos as permissões de “owner” (dono) da pasta ao seu usuário.

Vale lembrar de um ponto importante: todos os arquivos do Protheus no Linux, e inclusive estruturas de diretórios, por uma questão de convenção e compatibilidade estabelecidas no porte da aplicação para Linux, devem estar em letras minúsculas.

No nosso exemplo, vamos instalar apenas um Protheus 11 Server 64 bits. Para isso, eu proponho executar os comandos abaixo, para criar a seguinte estrutura de diretório:

mkdir /totvs/protheus11
mkdir /totvs/protheus11/envp11
mkdir /totvs/protheus11/bin_131227a

Para o exemplo acima, eu baixei apenas o Protheus 11 Server 64 em Linux, disponibilizado na seção de Download do portal da Totvs:

Arquivo    15-12-01-P11_APPSERVER_LINUX_X64.ZIP
Descrição  APPSERVER X64 700131227A  
Tamanho    59.6 MB

Primeiro, usando o WinSCP (SFTP), copie para a pasta ‘/totvs/protheus11/bin_131327a’ o arquivo “15-12-01-P11_APPSERVER_LINUX_X64.ZIP”.Após terminada a cópia, descompacte o arquivo usando o comando abaixo:

unzip 15-12-01-P11_APPSERVER_LINUX_X64.ZIP

A descompactação deve criar duas pastas, uma para os arquivos do Protheus Server , outra para o Smartclient Linux. Renomeie as pastas geradas para “appserver64” e “smartclient”, respectivamente, usando o comando “mv”, a partir da pasta /totvs/bin_131227a

mv appserverLinux_x64 appserver64
mv smartclientLinux smartclient

Entre na pasta appserver64, e descompacte todos os arquivos da pasta “appserver64”, usando os comandos abaixo:

cd appserver64
tar zxvf appsrvlinux_x64.tar.gz
tar zxvf printer_x64.tar.gz
tar zxvf libctreetmp_x64.tar.gz

Após descompactar, você pode remover todos estes arquivos com o comando:

rm -f *.tar.gz

Agora, vamos ajustar as propriedades de execução dos arquivos *.so do binário, usando o comando:

sudo chmod 777 *.so

Para o ambiente do ERP, Protheus 11, podemos criar toda a estrutura de pastas necessárias a partir da pasta /totvs/envp11, usando os comandos abaixo:

cd /totvs/protheus11/envp11
mkdir apo
mkdir data
mkdir system
mkdir systemload

Você pode pegar um repositório de objetos do portal, por exemplo o arquivo “16-06-14-BRA-EUA-PAR-URU-TTTP110.RPO”, bem como os demais arquivos necessários para criar um ambiente “do zero”, ou pode separar os arquivos necessários de seu ambiente Windows para montá-lo no Linux. O importante é que a versão do repositório do ERP deve ser a mesma versão dos arquivos de sistema (pasta ‘systemload‘).

Para um ambiente mínimo, você precisa da pasta “systemload” do seu ambiente Windows copiado na íntegra para o Linux, e na pasta “system” você precisa ter os arquivos com extensão XNU com as definições dos módulos do ERP, e de um arquivo “sigaadv.pss” do CD de instalação do ERP ou de um ambiente Windows. Este arquivo é usado como base para a criação do arquivo de senhas do ambiente, e parte do usuário “Admin”, sem senha (senha em branco). Se você já tem um ambiente Windows montado, você pode copiar o arquivo “sigapss.spf” deste ambiente para a pasta “system” do Linux.

Configurando o AppServer

Após copiar todos os arquivos necessários, vamos criar um arquivo de configuração para este ambiente no Protheus 11. Usando um editor no Windows ou no Linux, crie um arquivo chamado appserver.ini, com o seguinte conteúdo:

[general]
consolelog=1

[drivers]
active=tcp

[tcp]
type=tcpip
port=11010

[envp11]
sourcepath=/totvs/protheus11/envp11/apo
rootpath=/totvs/protheus11/envp11
startpath=/system/
rpodb=top
rpolanguage=por
rpoversion=110
localfiles=ctree

[dbaccess]
database=mysql
alias=envp11
server=localhost
port=7890

Este arquivo deve ser criado e/ou copiado para a pasta ‘/totvs/protheus11/bin_131227a/appserver64‘. Caso você já tenha um DBAccess com um banco de dados vazio configurado em uma máquina Windows, você pode apontar para ele. Esta sugestão de configuração já prevê o próximo post da sequência, onde vamos instalar um mysql e um DBAccess 64 bits no Linux, com unixodbc e tudo.

Nos testes atuais, eu subi um MSSQL Express na minha máquina Windows, usando um DBACcess Windows, e usei as seguintes configurações:

[dbaccess]
database=mssql
alias=envp11sql
server=192.168.1.63
port=7890

Para subir o Protheus Server em modo console no terminal Linux, entre na pasta /totvs/bin_131227a/appserver64, e use o comando:

./appsrvlinux

APPServer Linux 64

Agora, com todos os arquivos corretamente copiados para as devidas pastas no ambiente Linux, use um SmartClient da mesma Build, instalado na sua máquina Windows, edite o arquivo smartclient.ini, para criar uma nova conexão TCP para o Protheus Server no Linux, por exemplo:

[tcpubuntu14]
server=192.168.1.50
port=11010

Inicie seu SmartClient no Windows, utilizando os seguintes parâmetros:

Smartclient Win

Ao confirmar o início da aplicação, se tudo der certo, você deve ver uma tela rapidinha com uma mensagem “convertendo arquivo de senhas” e logo após uma tela de escolha de tema, parecida com a tela abaixo:

Smartclient Temas

As primeiras etapas de instalação do ERP, como por exemplo a criação do arquivo de Helps, é bem lenta no Linux. Quando eu digo que é lento, acredite em mim…

Isto é bem mais rápido, mesmo no Linux, quando usamos um c-Tree Server para controle dos dicionários. Também teremos um post exclusivo dedicado a esta etapa, onde inclusive vamos instalar o c-Tree Server nesta VM, e fazer os ajustes necessários no appserver.ini para passar a usá-lo.

Por padrão, os dicionários e arquivos locais de dados no Protheus Server usam o c-Tree. Como nesta instalação não foi instalado e configurado um c-Tree Server, o Protheus assume a utilização do driver local do c-Tree, chamado de “c-Tree Local”, que já vem distribuída junto com o binário do Protheus Server (arquivo libctreestd.so).

Usando o Protheus com o c-Tree BoundServer

Quando temos uma instância única de Protheus Server, podemos também fazer uma alteração simples e muito eficaz: Usar o “c-tree Server DLL” (ou c-Tree BoundServer) neste ambiente … É extremamente simples, mas você somente pode ter um único serviço de Protheus Server configurado para acessar este ambiente: Você edita o appserver.ini (sem que o Protheus Server esteja em execução), e na seção [general], acrescenta a chave:

ctreemode=boundserver

Ao subir novamente o Protheus Server, ele vai usar uma versão do c-Tree Server “embarcada”, que já vem junto do pacote de distribuição do Protheus Server, para ser o gerenciador dos arquivos, ao invés do c-Tree Local.

No meu ambiente de testes, a criação dos arquivos de help já tinha consumido mais de 20 minutos, e ainda não tinha concluído nem a metade … Derrubei o Protheus Server, que rodava em modo console, usando Control+C, e fiz a alteração acima.

Embora no momento de subir o Protheus Server, o c-Tree BoundServer tenha reclamado que faltava um arquivo de “Callback”, o serviço subiu no ar certinho. Utilizando o WINSCP, apaguei da pasta “system” o arquivo “sigahlp.hlp”, que não tinha sido criado completo, e entrei no ERP novamente usando o SmartClient no Windows.

Utilizando o c-Tree BoundServer, a atualização do arquivo de Help e a tela de entrada do ERP apareceram em menos de 30 segundos.

Após digitar usuário e senha, e na segunda tela confirmar a data do dia, e entrar no módulo configurador, na empresa 99 – Teste (criada automaticamente na entrada do sistema), é perguntado qual país de instalação do ERP. Escolha “Brasil” e prossiga. O resto do procedimento é padrão da instalação do produto: Após criar um ou dois dicionários, o ERP pergunta qual é a pasta de dados. Esta pergunta foi mantida por compatibilidade no instalador. Por compatibilidade, escolha a pasta “data”.Em poucos minutos a carga inicial é finalizada, e o menu do módulo configurador do ERP é mostrado na tela.

 

Observações sobre o c-Tree BoundServer

  • Pode ser usado para gerenciador dos dicionários no lugar do c-Tree Server tradicional, desde que apenas uma instância do Protheus Server acesse os arquivos do ambiente.
  • Possui licença subsidiada para até 64 conexões.
  • Por default, o c-Tree BoundServer distribuído junto dos executáveis do Protheus Server está configurado para não aceitar conexões TCP.
  • Existem mais detalhes a respeito, que serão abordados em posts dedicados a este assunto 😀

Conclusão

Para um serviço “stand-alone”, sem o SGDB na máquina Linux, já temos bastante coisa funcionando. Nos próximos posts a respeito, vamos ver como colocar um MYSQL nesta máquina Linux, junto com um DBAccess 64 bits, e conectar o Protheus Server neste banco.

Ainda não chegamos no ponto de usar mais de um serviço, ou mesmo balanceamento de carga … mas não se preocupem, chegaremos lá aos poucos 😀  Agradeço de novo a audiência de todos, e lhes desejo sempre TERABYTES de sucesso 😉

Até o breve próximo post, pessoal !!!