# Depanare actualizare ROA (CONTAFIN_ORACLE.PACK_UPDATE) Actualizarea automata a aplicatiilor si a bazei ruleaza din jobul `CONTAFIN_ORACLE.UPDATEROA_ZILNIC` -> `PACK_UPDATE.UpdateROA`, in 3 etape secventiale: **UpdateApp** (descarca arhivele programelor) -> **UpdateScripts** (umple `UPD_DATABASE`) -> **UpdateDatabaseSqlPlus** (aplica scripturile pe scheme). O etapa esuata le opreste pe toate urmatoarele. ## Unde te uiti, in ordine | Ce | Unde | |---|---| | pana unde a ajuns fiecare rulare | `UPD_ISTORIC` (`stare`: 0=start, 1=aplicatii, 2=scripturi, 3=aplicare, 4=incheiat; `dataora_end` gol = neincheiata) | | cauza reala a esecului | `UPD_LOG` (`dataora_start` = rularea, `secventa`+`dataora` = ordinea; `explicatie` e CLOB) | | ce a raportat jobul | `dba_scheduler_job_run_details` (`log_date`, `status`, `additional_info`) | | ce versiuni s-au descarcat | `UPD_PROGRAME` | | scripturi disponibile / aplicate | `UPD_DATABASE.script_date` vs `.VERSIUNE.data_script` | | **erorile din aplicarea scripturilor** | **`C:\DMPDIR\script_master.log` pe serverul de baze de date** | Un sir de rulari oprite la aceeasi `stare` da direct etapa vinovata, iar prima zi din sir da data de la care s-a schimbat ceva. ## Capcane - **`UPD_LOG` se goleste la fiecare rulare.** Nu ai istoric: iei log-ul rularii curente, altfel relansezi ca sa-l reproduci. - **Eroarea din `additional_info` a jobului e de obicei falsa.** Pe orice esec se apeleaza `EmailLog`, iar daca SMTP-ul e picat ridica `ORA-20000` care inlocuieste eroarea originala. Cauza adevarata e in `UPD_LOG`. - **`UpdateApp` abandoneaza tot la primul program nedescarcat** (`exit` din bucla, `CT_INSUCCES`) — deci si programele de dupa el in lista, si ambele etape de baza de date. Un singur fisier indisponibil blocheaza actualizarile la infinit, tacut. - **`GetStare` refuza o rulare noua** cat timp precedenta e neincheiata si nu a trecut o ora. Se deblocheaza cu `exec contafin_oracle.pack_update.IncheiereActualizare`. - Programele `%USERREPORTS%` merg toate in directorul `UPD_USERREPORTS`, nu in `UPD_`. ## Aplicarea scripturilor (script_master.log) Etapa 3 nu ruleaza scripturile din PL/SQL, ci genereaza in `DMPDIR` (`C:\DMPDIR`) cate un `script_.sql` plus `script_master.sql`, pe care le da unui **SQL\*Plus extern**, cu iesirea in `C:\DMPDIR\script_master.log` (`script_master2.log` = pasii de la final). **Erorile de aici NU ajung in `UPD_LOG`.** O rulare care esueaza la un script arata perfect curata in baza: `UPD_LOG` fara nicio eroare, doar `UpdateSchemaSQLPLUS ... / UpdateDatabaseSQLPLUS END`. Semnele indirecte sunt ca rularea ramane la `stare = 3` fara `dataora_end`, iar `.VERSIUNE` nu mai avanseaza. Scriptul vinovat e primul din `UPD_DATABASE` de dupa ultima versiune inregistrata acolo, iar mesajul real e doar in `script_master.log`. Scripturile au `WHENEVER SQLERROR EXIT SQL.SQLCODE ROLLBACK`, deci primul esec opreste tot lantul si se repeta identic la fiecare rulare pana e reparat. Fisierul se poate citi si fara acces la desktopul serverului, prin `UTL_FILE` pe directorul `DMPDIR` (`fopen(...,'R',32767)` + `get_line` in bucla; tine ultimele N linii intr-un tablou — partea utila e la sfarsit). ## Descarcarea (UpdateApp) Cu `server_info.POWERSHELLDOWNLOAD = '1'`, `PACK_UTILS.DownloadFileOS` scrie un `.ps1` cu `curl` in `DMPDIR`, il lanseaza cu `sys.ExecuteScriptOS` si asteapta aparitia fisierului in directorul Oracle `UPD_`. Daca **folderul de pe disc lipseste**, curl esueaza mut si in log apare doar `Fisierul NU s-a salvat pe disc.` — verifica intai directorul, nu reteaua. Verificari rapide (read-only, din `contafin_oracle`): ```sql -- calea configurata select directory_name, directory_path from all_directories where directory_name like 'UPD%'; -- fisierul chiar exista pe disc? select dbms_lob.fileexists(bfilename('UPD_ROACONT','ROACONT-2.11.70.zip')) from dual; ``` ```sql -- directorul exista si e scriibil? ORA-29283 = cale OS inexistenta sau fara drept de scriere declare f utl_file.file_type; begin f := utl_file.fopen('UPD_USERREPORTS','__probe.txt','W'); utl_file.fclose(f); utl_file.fremove('UPD_USERREPORTS','__probe.txt'); end; / ``` URL-ul se testeaza direct cu `curl` de pe orice masina (`optiuni.UPD_URL_APP`, cu `|CUSTOMERID|` inlocuit din `sys.auth_detalii.detalii`); daca da 200, problema e local pe server. ## Comenzi OS pe serverul de baze de date `sys.ExecuteScriptOS(, )` creeaza un job scheduler `executable` — **asincron**, deci rezultatul se verifica prin polling, nu imediat. Scriptul se scrie cu `pack_utils_file.clob2fileX(, 'DMPDIR', '.ps1')`. Utila cand ai doar acces Oracle (ex. tunel SSH), fara RDP: ```sql declare lcPS server_info.value%type; begin select value into lcPS from server_info where upper(name)='POWERSHELLPATH'; pack_utils_file.filedelete('DMPDIR','x.ps1'); pack_utils_file.clob2fileX('New-Item -ItemType Directory -Force -Path ''D:\...'' | Out-Null', 'DMPDIR','x.ps1'); sys.ExecuteScriptOS(lcPS, 'C:\DMPDIR\x.ps1'); end; / ``` ## Emailuri: log de actualizare vs buletin informativ Sunt **doua emailuri diferite, trimise de doua masini diferite** — se confunda usor. | | Log de actualizare | Buletin informativ | |---|---|---| | Cine trimite | baza de date, `PACK_UPDATE.EmailLog` (`UTL_SMTP` direct catre `EMAIL_SMTP:EMAIL_PORT`, `AUTH LOGIN`) | **serverul de update** (ASP.NET); baza doar face un GET pe `optiuni.UPD_URL_BULETININF` (cu `|CUSTOMERID|`) prin `PACK_UTILS.URL2Clob`, din `UpdateApp` | | Destinatari | `server_info.EMAIL_TO` + `EMAIL_CC` | configurati pe serverul de update, **nu** in `server_info` (ex. `office@romfast.ro`) | | Subiect / continut | `Actualizare ROA dd.mm.yyyy hh24:mi:ss`; liniile din `UPD_LOG`, text simplu separat cu TAB | compus de serverul de update | | In `UPD_LOG` | erorile SMTP: `EROARE: utl_smpt ERROR CODE ...` | raspunsul HTTP, verbatim (ex. `ERR-1-BULETIN INFORMATIV NU S-A TRIMIS. MOTIVUL: Error: 1429`) | Detalii care conteaza la depanare: - **`EMAIL_CC` nu produce un antet `Cc:`.** Codul il concateneaza cu virgula la `EMAIL_TO` si trimite `RCPT TO` pentru toti; antetul e un singur `To: `. Deci un email primit *in Cc* nu vine de la `EmailLog`. - **`EMAIL_FROM` e per server de client** (`roaupdate-@romfast.ro`) si difera de contul autentificat, care e acelasi peste tot (`EMAIL_USERNAME = roaupdate@romfast.ro`). Expeditorul e singurul indiciu din email despre serverul care l-a trimis. Daca `EMAIL_FROM` lipseste, se compune din `UTL_INADDR.get_host_name`. - **Un buletin esuat nu opreste nimic**: raspunsul `ERR-1-...` e text normal, se scrie in `UPD_LOG` si actualizarea merge mai departe. Doar exceptiile HTTP ajung ca `ERR: ...`. - **Un SMTP picat, in schimb, opreste tot** — `EmailLog` ridica `ORA-20000` care mascheaza eroarea reala (vezi „Capcane" mai sus). E singurul loc din lantul de email care are voie sa arunce. ## Configurare (CONTAFIN_ORACLE) - `server_info`: `POWERSHELLDOWNLOAD`, `POWERSHELLPATH`, `POWERSHELLTIMEOUT`, `CURLPATH`, `SQLPLUSPATH`, `EMAIL_METHOD`/`EMAIL_SMTP`/`EMAIL_PORT`/`EMAIL_USERNAME`/`EMAIL_PASSWORD`/ `EMAIL_FROM`/`EMAIL_TO`. - `optiuni`: `UPD_URL_APP`, `UPD_URL_DATABASE`, `UPD_URL_BULETININF` (daca lipsesc, pachetul foloseste URL-uri implicite din cod). ## Conectare la serverul unui client Tunel SSH pe 1521 + alias TNS pe `127.0.0.1` in `D:\ROA\instantclient_19_18\tnsnames.ora` (ex. `ROA_ROMCONSTRUCT`), utilizator `contafin_oracle`. Vezi `oracle_export.md` pentru client si capcana de encoding; parolele stau in `docs/local/` al proiectului, neversionat. Serverele de client pot fi Oracle 10g: unele coloane din `dba_scheduler_*` lipsesc (`dba_scheduler_running_jobs.last_start_date`) — foloseste `dba_scheduler_job_run_details`.