Pular para conteúdo

Instalação e operação

Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-09-21

Provisionar uma instalação nova (lado X-Adm — antes de ir ao cliente)

  1. Par de chaves da instalação (a privada é a credencial do cliente):
    openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out <cliente>-private.pem
    openssl rsa -in <cliente>-private.pem -pubout -out <cliente>-public.pem
    
  2. Registrar a pública no PowerSync do cliente: converter para JWK (modulus base64url) e colocar inline em client_auth.jwks.keys do powersync.yaml (repo powersync do cliente), com kid novo (ex.: <cliente>-ps-v1) e audience do cliente; rebuild + redeploy da imagem (config assada).
  3. Token de write-back: o INTEGRADOR_API_TOKEN da instância do Integrador do cliente (env no Coolify) — é o que vai em powersync.upload.token. O mesmo token autentica o heartbeat.
  4. Montar o pacote: dist/ com o fat jar (./gradlew shadowJar), o integrador-client.properties preenchido (URLs, jwt.kid/issuer/audience/subject casando com o passo 2, caminhos do ZIM reais, cliente=<slug> para a observabilidade) e o <cliente>-private.pem.
  5. Validar antes de entregar: rodar --debug apontando para a instância real — conectar, [r] listar pendentes; processar só com aval do cliente (grava status na nuvem). O programa pAbast precisa estar instalado no ZIM (contrato).

Requisitos

  • Máquina do ERP (Windows x64) com Java 8 ou superior (java -version).
  • ERP X-Adm instalado, com o programa ZIM pAbast desta integração (contrato).
  • Acesso HTTPS de saída para ps.<cliente>.xadm.biz e int.<cliente>.xadm.biz — só isso: o heartbeat usa o mesmo int.<cliente> do write-back, sem liberação nova de firewall.

Instalar

  1. Crie uma pasta (ex.: C:\integrador-client) e coloque nela os arquivos entregues:
  2. integrador-client-<versão>.jar
  3. integrador-client.properties (a partir do integrador-client.properties.exemplo)
  4. <cliente>-private.pem — credencial da instalação; não copiar, não enviar
  5. rodar.bat
  6. Preencha o integrador-client.properties (o exemplo documenta cada chave; as principais: URLs da nuvem, token de upload, caminho do zimrtmu.exe e da pasta do X-Adm).

Caminhos com espaços são aceitos. Use /, não coloque aspas e mantenha cada propriedade em sua própria linha, por exemplo:

zim.executavel=C:/Program Files (x86)/Zim/7.11/zimrtmu.exe
zim.diretorio=D:/XADM/XADMUSR/xadmXApiMDFe1
3. Teste: java -jar integrador-client-<versão>.jar --version deve imprimir a versão. 4. Inicie com rodar.bat. A primeira linha do log é a versão; em seguida o programa conecta, sincroniza e passa a processar pendentes a cada ciclo. 5. Para iniciar junto com o Windows: agende o rodar.bat no Agendador de Tarefas ("Ao iniciar o computador", conta local, "Executar estando o usuário conectado ou não").

Modo debug (homologação com a equipe ZIM)

java -jar integrador-client-<versão>.jar --debug

Nada roda sozinho: o operador comanda pelo console o que processar — [i]tem (1 registro = 1 linha no arquivo de envio), [p]edido (o próximo contrato pendente com cliente/fones/produtos/itens num arquivo só), [t]udo (um ciclo normal), [r]ecarregar a lista de pendentes, [s]air. Cada comando gera o arquivo de envio, roda o pAbast e mostra no console as linhas do envio e do retorno entre |pipes| (padding visível) + o resultado; ao final, a lista de pendentes é recarregada sozinha. No debug os arquivos dXpEnvio/dXpRetorno ficam no disco (na pasta do X-Adm) para inspeção, com a máscara do layout anexada ao final e as versões dXpEnvio.json/dXpRetorno.json (pretty print) ao lado — o próximo processamento apaga e reescreve; no modo normal os arquivos são apagados após aplicar. A sincronização com a nuvem continua normal em segundo plano.

Acompanhar

  • Logs em logs\integrador-client.log (o dia corrente); ao virar o dia, o anterior é zipado como logs\anomesdia.integrador-client.log.zip (30 dias guardados).
  • Linha de sucesso de um lote: lote aplicado: N gravado(s), … seguida dos write-back … aceito.
  • Saída do próprio ZIM: pAbast-saida.log na pasta do X-Adm (sobrescrito a cada lote). Quando o lote falha, as últimas linhas dela vão também para o log do cliente (saída do pAbast …).
  • Sinal de vida: heartbeat enviado (inicio) na largada e heartbeat enviado (periodico) a cada hora. A instalação aparece sozinha na aba Deploy do central-ui, com a versão e os fluxos.

Heartbeat (sinal de vida)

Na largada e a cada intervalo o programa avisa a plataforma que está vivo: versão, fluxos ativos e nome da máquina. O central acompanha e alerta quando uma instalação passa de 6 horas úteis sem sinal (runbook do central). Não há nada obrigatório a configurar; as duas chaves são opcionais:

Chave Padrão O que faz
heartbeat.url o powersync.upload.url com o caminho /api/v1/heartbeat endereço do heartbeat; URL malformada para na largada (exit 2)
heartbeat.intervaloMinutos 60 minutos entre heartbeats; 0 desliga (inclusive o da largada); negativo para na largada

O heartbeat nunca derruba o programa: qualquer falha só vira WARN no log. O --debug não manda heartbeat. O contrato é do integrador-server: heartbeat.md.

Encerrar / reiniciar

Fechar a janela (ou finalizar o processo java.exe) é seguro em qualquer momento: lote em andamento volta a pendente sozinho na próxima subida (recuperação automática), e a fila de write-back fica guardada no banco local — nada se perde.

Exit codes

Seguem a taxonomia da casa (contrato canônico):

Exit Significado no integrador-client
0 encerramento normal (interrupção pedida)
1 falha inesperada no daemon (ver log)
2 configuração/ambiente inválido — properties com chave faltando/errada ou JVM 32 bits (a extensão nativa do PowerSync não carrega; rode com Java 64 bits). A mensagem diz qual dos dois
4 ocupado: outra instância já roda nesta pasta de dados (lock); nada foi feito, seguro tentar depois

(3 = erro externo não é usado: falha de rede/nuvem não derruba o daemon — o SDK retenta sozinho.)

Problemas comuns

Sintoma Causa provável O que fazer
Sai na hora com "erro de configuração: chave …" (exit 2) properties incompleto ou caminho errado corrigir a chave citada na mensagem
Sai na hora com "Necessário Java 64 bits …" (exit 2) rodou com o java 32 bits do PATH apontar pra uma JRE 64 bits (o PowerSync só carrega em 64 bits)
pAbast não terminou em Ns — matando o processo falta de licença ZIM ou ZIM travado nada — o lote tenta de novo sozinho; se persistir, liberar licença
pAbast terminou com exit code N falha geral do ZIM ver pAbast-saida.log na pasta do X-Adm
retorno inválido — lote volta a pendente pAbast escreveu retorno fora do contrato conferir o contrato §4
retorno do pAbast com N linha(s) de tentativa abortada … descartadas o ZIM deu conflito, recomeçou o lote e não limpou o dXpRetorno nada — o cliente aproveitou a rodada final e aplicou o lote normalmente; é defeito do ZIM a corrigir (contrato §4 e §8)
retorno do pAbast ecoou a linha de continuação 'IMPORTA_PIED' como registro — descartada o ZIM deu conflito e respondeu também à linha de continuação nada — os 999 foram aplicados e o lote retenta sozinho; é defeito do ZIM a corrigir (contrato §4 e §8)
pAbast falhou depois do handshake … Conferir no ERP: … o ZIM caiu no meio do lote (exit ≠ 0, travou ou retorno fora do contrato) e pode ter gravado parte o lote é reenviado sozinho; conferir no ERP os registros citados (cadastro duplicado, item sem pedido). O dXpRetorno e a saída do ZIM estão no log logo acima
write-back … HTTP 4xx/5xx repetido token errado ou nuvem fora conferir powersync.upload.token; a fila re-tenta sozinha
heartbeat recusado: HTTP 401 token errado (é o mesmo do write-back) conferir powersync.upload.token
heartbeat recusado: HTTP 404 o integrador-server do cliente ainda não tem a rota do heartbeat (versão antiga) atualizar o integrador-server do cliente; o programa segue normal enquanto isso
heartbeat recusado: HTTP 502 o integrador-server não conseguiu repassar ao central (central fora, ou o central recusou) transitório se passar sozinho; se repetir, ver o log do integrador-server (heartbeat_recusado = config errada lá)
heartbeat recusado: HTTP 503 falta CLIENTE_ID ou CENTRAL_API_TOKEN no integrador-server do cliente configurar as envs no Coolify do integrador-server
heartbeat não entregue: … rede ou integrador-server fora do ar nada — o próximo heartbeat tenta de novo
401 ao conectar no PowerSync chave PEM/kid/audience não batem com a instância conferir chaves jwt.* e o .pem
Registro parado em 1XX erro de dado (terminal) corrigir o dado na origem (nuvem); o registro não é retentado

Erros de configuração (exit 2) ficam no console e em logs/integrador-client.log, com a chave e o caminho a corrigir. Eles não abrem incidente no GlitchTip/Sentry porque exigem correção local da instalação, não investigação de falha do aplicativo.

O que vai para o GlitchTip

O programa roda na máquina do cliente, então o que chega ao GlitchTip (bug.xadm.biz, projeto integrador-client) é o que dá para diagnosticar de longe. Filtre por cliente:<slug> — o slug é a chave cliente do .properties.

Vira incidente Não vira
todo WARN e ERROR do programa, com a exceção anexada quando há erro de configuração e JVM de 32 bits (ação do operador, não falha do app)
remessa travada ou retida, uma vez por causa conflito de concorrência no dRels3 — o lote retenta sozinho
erro terminal no encerramento de MDF-e o eco do dXpEnvio/dXpRetorno, que viaja dentro do incidente

Cada incidente carrega junto: as linhas cruas do dXpEnvio e do dXpRetorno do lote (em blocos, entre |pipes|, como no log local), os marcos do ciclo, e a configuração com que o processo subiu — com powersync.upload.token e a chave privada mascarados, como no log.

As linhas cruas levam dado de cliente

O layout do pAbast tem cgc_cpf, nome_prop e fantasia: CPF/CNPJ e nome aparecem no incidente. É decisão consciente — o GlitchTip é hospedado na infraestrutura da X-Adm, não em serviço de terceiro, e o evento é descartado pela retenção de 90 dias. Quem lê o projeto é quem já tem acesso ao GlitchTip da casa.

Desligar o envio

Suba o programa com a variável de ambiente SENTRY_DSN vazia:

set SENTRY_DSN=
java -jar integrador-client-<versão>.jar

A variável, quando definida, vence o app.json embarcado no jar — vazia desliga, preenchida manda para o projeto que ela apontar. É assim que o e2e local e o desenvolvimento rodam sem sujar o painel de produção. Sem a variável definida, vale o DSN do jar.

Para conferir o caminho até o GlitchTip numa instalação nova:

java -jar integrador-client-<versão>.jar --sentry-teste

O evento de teste sai com environment=smoke e cliente=smoke — não se mistura com incidente de cliente real.

Atualizar versão

Parar o programa, trocar o jar pelo novo (mesma pasta), iniciar de novo. O banco local e o properties são preservados.

Ao passar para a primeira versão com heartbeat, o integrador-server do cliente precisa já ter a rota do heartbeat. Na ordem inversa o programa só loga WARN 404 a cada hora, mas o integrador-server registra ERROR a cada chamada autenticada que não acha a rota.