# Depanare serverul de actualizari ROA (ROACENTRAL / contafinupdate) Completeaza `depanare-pack-update.md`: acolo e vorba de ce se intampla **pe baza clientului**, aici de ce se intampla **pe serverul care livreaza actualizarile**. Foloseste documentul asta cand `PACK_UPDATE` esueaza cu erori de retea / HTTP, adica atunci cand clientul e in regula dar nu primeste fisierele. Ansamblul fluxului, fara depanare: `flux-actualizare-si-buletine.md`. ## Lantul complet, de la eroare la cauza ``` job UPDATEROA_ZILNIC -> PACK_UPDATE.UpdateROA -> PACK_UTILS.URL2Clob / URL2Blob daca SERVER_INFO.POWERSHELLDOWNLOAD = 1: -> PACK_UTILS.DownloadFileOS -> scrie C:\DMPDIR\download_.ps1 (pana la co_2026_09_16_02: download_file.ps1) -> sys.ExecuteScriptOS -> powershell -> curl.exe -k -o .part , redenumit la final (pana la co_2026_09_16_02: direct in ) -> asteapta max SERVER_INFO.POWERSHELLTIMEOUT secunde sa apara daca fisierul NU apare (sau POWERSHELLDOWNLOAD <> 1): -> cade pe HTTPURITYPE.createuri(url).getclob()/getblob() ``` **Consecinta cea mai importanta:** pe un URL `https`, ramura de rezerva `HTTPURITYPE` **nu poate functiona** - Oracle nu are wallet cu CA-urile, deci da mereu: ``` ORA-29273: nu s-a reusit solicitarea HTTP ORA-29024: Validarea certificatului a esuat ORA-06512: la "CONTAFIN_ORACLE.PACK_UTILS", linia 304 <- HTTPURITYPE ORA-06512: la "CONTAFIN_ORACLE.PACK_UPDATE", linia 321 <- URL2Clob(roa_app.xml); 750 = roa_database.xml ``` **ORA-29024 NU inseamna ca e o problema de certificat.** Inseamna ca descarcarea cu `curl` a esuat si s-a ajuns pe ramura moarta. Cauza reala e ca **serverul de actualizari nu a raspuns**. Nu pierde timp cu wallet-uri si certificate pana nu ai verificat serverul. Al doilea capcan: `UPD_ISTORIC` poate arata `stare=4` (incheiat) chiar si pentru rulari care au esuat, iar `UPD_LOG` se goleste la fiecare rulare noua. Sursa de adevar pentru esec e `user_scheduler_job_run_details` / `dba_scheduler_job_run_details` (`status`, `additional_info`). ## Primul lucru de verificat: chiar nu raspunde serverul? De pe masina clientului (nu de pe statia ta - firewall-ul serverului filtreaza pe IP): ``` curl.exe -k -s -o NUL --max-time 20 -w "HTTP=%{http_code} t=%{time_total}" "https://roa.romfast.ro/contafinupdate/default.aspx/updroa/download//roa_app.xml" ``` `HTTP=000` cu `t` egal cu `--max-time` = blocat (nu refuzat). `exit=28` = timeout. Ultima comanda reala rulata de Oracle e in **`C:\DMPDIR\download_*.ps1`** (un singur fisier, cu nume fix, pana la co_2026_09_16_02) pe serverul clientului - contine URL-ul exact si numele fisierului tinta. Daca `.tmp`-ul corespunzator nu exista, stii sigur ca descarcarea a picat. `CUSTOMERID` si URL-urile efective le iei din baza clientului: ```sql select varname, varvalue from optiuni where varname like 'UPD_URL%'; select name, value from server_info where name in ('POWERSHELLDOWNLOAD','POWERSHELLPATH','POWERSHELLTIMEOUT','DMPDIR','NAME'); ``` Daca `OPTIUNI.UPD_URL_*` sunt completate, ele bat default-urile din `PACK_UPDATE` (`http://10.0.20.122:81/...` intern / `http://83.103.197.79:3002/...` extern). ## Serverul: ROACENTRAL, 10.0.20.122 | Ce | Unde | |---|---| | acces | `ssh romfast@10.0.20.122` (OpenSSH for Windows, shell implicit **PowerShell**) | | aplicatie | ActiveVFP, `D:\APPUPDATESERVERAVFP` (sit IIS "Default Web Site", pool `DefaultAppPool`) | | cod rute updroa | `D:\APPUPDATESERVERAVFP\prg\rest\controllers\updroa.prg` (+ `.FXP`) | | **log aplicatie** | `D:\APPUPDATESERVERAVFP\prg\rest\controllers\log.txt` | | config | `D:\APPUPDATESERVERAVFP\appupdateserver.ini` (DSN, user, parole, caile de download) | | fisiere livrate | `D:\ROAUPDATE\_UPDATE\` (si `ROA_APP_.xml` / `ROASTART_APP_.xml` per client) | | loguri IIS | `C:\inetpub\logs\LogFiles\W3SVC1\u_ex.log` | Testeaza **local pe server**, ocolind proxy-ul (roa.romfast.ro trece prin 10.0.20.36): ```powershell curl.exe -k -s -o NUL --max-time 15 --resolve roa.romfast.ro:443:127.0.0.1 -w "HTTP=%{http_code} t=%{time_total} sz=%{size_download}" "https://roa.romfast.ro/contafinupdate/default.aspx/updroa/download/18/roa_app.xml" ``` Daca se reproduce asa, proxy-ul si reteaua sunt nevinovate. **Testeaza mai multi clienti.** Daca unii merg si altii nu, nu e nici situl, nici pool-ul: parcurge `17,18,19,29,105,118,121` pe aceeasi ruta si compara timpii. Capcane de mediu, ca sa nu tragi concluzii gresite: - portul **81** e filtrat de firewall pentru alte masini, desi `netstat` arata `0.0.0.0:81 LISTENING`. "Inchis de pe LAN" nu inseamna "sit oprit". - pe portul 80 fara `Host:` corect primesti **404 de la `Microsoft-HTTPAPI/2.0`** (http.sys), pentru ca niciun sit nu prinde cererea. Nu inseamna ca IIS e picat. - `Get-WebRequest` / `appcmd list requests` nu sunt instalate (`Not implemented`). - `Get-Service` esueaza pentru contul `romfast` (drepturi), dar `Get-Website` / `Get-WebAppPoolState` merg. - daca pool-ul ramane in starea `Stopping`, procesele `w3wp` blocate nu ies singure; le identifici cu `C:\Windows\System32\inetsrv\appcmd.exe list wp` si le opresti cu `Stop-Process -Id -Force`. ## Cauza gasita pe 16.09.2026: sesiune Oracle agatata pe db link Simptom: **doar un client** (id 18, conpress) primea timeout la orice ruta; toti ceilalti erau serviti in 0.2s. In `log.txt` cererile clientului blocat se opreau exact dupa `GetCustomer ` (`updroa.prg:635`), fara linia `GetCustomer sql ...` (`updroa.prg:703`). `GetCustomer` interogheaza `SOFT_SERII.VGEN_CONTRACTESUPORTTEHNIC` pe **ROA_CENTRAL (10.0.20.121:1521/ROA)**, iar view-ul ia `data_inceput / data_sfarsit / incetat / suspendat` peste **db link `DBL_ROMFAST2` -> `ROMFAST.CONTRACTE` pe 10.0.20.36**. Diagnostic (de pe orice statie, nu e nevoie de tunel): ``` set TNS_ADMIN=D:\ROA\instantclient_19_18 D:\ROA\instantclient_19_18\sqlplus.exe -S -L soft_serii/@ROA_CENTRAL ``` ```sql select sid, username, program, machine, status, event, seconds_in_wait, blocking_session from v$session where username is not null and type='USER' order by status, seconds_in_wait desc; ``` Ce a iesit: ``` SID 199 SOFT_SERII w3wp.exe ACTIVE single-task message 51770 (blocanta) SID 148 SOFT_SERII w3wp.exe ACTIVE cursor: pin S wait on X 69 blocked by 199 SID 246 SOFT_SERII w3wp.exe ACTIVE cursor: pin S wait on X 66 blocked by 199 ``` - `single-task message` = sesiunea asteapta un apel remote pe db link care nu se mai intoarce. - Sesiunea agatata **tine pinul X pe cursorul SQL-ului ei**, deci orice cerere noua cu **exact acelasi text SQL** asteapta `cursor: pin S wait on X`. - `updroa.prg` pune literalul in SQL (`... where id_client = 18`), nu bind variable. De aceea **blocajul afecteaza exact un client** si pare "problema doar la el". Cu bind variables ar fi blocat toti clientii deodata - mai vizibil, dar aceeasi cauza. Detalii despre sesiunea vinovata: ```sql select s.sid, s.serial#, to_char(s.logon_time,'DD.MM.YYYY HH24:MI:SS'), s.sql_id, s.event, s.seconds_in_wait from v$session s where s.sid = ; select sql_id, substr(sql_text,1,200) from v$sql where sql_id in (select sql_id from v$session where sid=); ``` `logon_time` da momentul exact in care s-au rupt lucrurile (aici 15.09.2026 20:30:25 UTC = 23:30 local, adica fix rularea jobului de actualizare al clientului). **Deblocare** (ca SYS pe ROA_CENTRAL): ```sql alter system kill session ',' immediate; ``` Dupa kill, totul revine imediat - nu e nevoie de restart de sit sau de recycle de pool. ### Ce NU rezolva, desi pare (verificat, s-a pierdut timp pe ele) - restart sit IIS / `Restart-WebAppPool` - sesiunea blocata e pe serverul Oracle si supravietuieste omorarii lui `w3wp`; - restart Windows pe serverul de update - acelasi motiv; - wallet / certificate pe clientul Oracle - ORA-29024 e simptom, nu cauza; - stergerea cache-ului local `D:\APPUPDATESERVERAVFP\data\contracte.dbf` + `.CDX` (e recreat singur de `updroa.prg:683-688`, deci e un test ieftin si reversibil, dar in cazul asta a fost negativ). ## Lista scurta de verificare 1. `user_scheduler_job_run_details` pe clientul afectat: care e eroarea reala si **din ce zi**. 2. scriptul `download_*.ps1` din `C:\DMPDIR` pe client: URL-ul exact; exista `.tmp`-ul? 3. `curl` de pe client pe acel URL: raspunde sau timeout? 4. Pe ROACENTRAL, `curl` local cu `--resolve`, pentru mai multi clienti: e global sau doar unul? 5. `log.txt` al aplicatiei: pana la ce linie ajunge cererea blocata. 6. `v$session` pe ROA_CENTRAL: `single-task message` / `cursor: pin S wait on X` / `blocking_session`. Cauta `seconds_in_wait` mare si compara `logon_time` cu ziua din pasul 1. 7. `alter system kill session` pe sesiunea blocanta; reverifica pasii 3-4. De urmarit daca se repeta: de ce se agata linkul `DBL_ROMFAST2` spre 10.0.20.36 (timeout de retea fara detectie - merita un `SQLNET.EXPIRE_TIME` / `outbound_connect_timeout` pe link-ul respectiv). ## Anatomia fallback-ului PACK_UTILS: de ce ORA-29024 nu inseamna certificat Referinta: `SCRIPTURI_CLAR/2026/09/co_2026_09_16_02_COMUN_PACK_UTILS.sql`. `URL2Clob` (linia 333) si `URL2Blob` (linia 284) lucreaza pe **acelasi** `tcURL` si au **doua** ramuri de transport una dupa alta; nu exista un URL separat "fara SSL". URL-ul vine din `optiuni.UPD_URL_APP` (vezi mai sus). **Ramura 1 - curl extern.** Se intra doar daca `SERVER_INFO.POWERSHELLDOWNLOAD = '1'` (`URL2Clob`:347, `URL2Blob`:298). `DownloadFileOS` (`URL2Clob`:353, `URL2Blob`:304) scrie un script PowerShell cu `curl.exe -k -o ".part"` (linia 756), il ruleaza prin `sys.ExecuteScriptOS` (linia 766) si asteapta prin polling pana la `SERVER_INFO.POWERSHELLTIMEOUT` secunde (implicit 60: linia 696, bucla liniile 771-775) sa apara fisierul final; redenumirea din `.part` o face `$LASTEXITCODE` (linia 758). Criteriul de succes e **doar existenta fisierului** (liniile 772-773 si 777-778). **Ramura 2 - HTTPURITYPE.** Se atinge cand `llDownloaded = FALSE` **sau** cand `POWERSHELLDOWNLOAD <> '1'`: nu exista `ELSE`, se cade direct la `HTTPURITYPE.createuri(tcURL).getclob()` (`URL2Clob`:367) / `getblob()` (`URL2Blob`:318). Pe URL `https` fara wallet, asta da **mereu** `ORA-29273 / ORA-29024`. **Consecinta - miezul sectiunii.** Codul de iesire al `curl.exe` (conexiune refuzata, timeout, 502) e folosit doar ca sa se decida daca `.part` se redenumeste (linia 758); valoarea nu se logheaza si nu se pastreaza nicaieri. Singurul semnal care ajunge inapoi la Oracle ramane `llDownloaded = FALSE`. De aceea `ORA-29024` e zgomotul caderii, nu cauza, si cauza reala trebuie reconstruita din alta parte (`v$session`, log-ul serverului de update). **Ce sa verifici cand vezi ORA-29024**, in ordinea asta: 1. raspunde serverul de update pentru clientul ala? (`curl` de pe client, vezi mai sus); 2. `POWERSHELLDOWNLOAD` e `'1'` pe instanta clientului? 3. `ExecuteScriptOS` functioneaza pe instanta (POWERSHELLPATH completat, drepturi, directorul de descarcare scriibil)? Un job `EXEC_PS_*` cu `SUCCEEDED` **nu** dovedeste ca si `curl` a reusit: scriptul iese cu 0 si cand descarcarea a esuat. Un `.part` ramas in DMPDIR arata ca procesul nativ nu a fost asteptat. 4. abia la urma wallet-ul / certificatele - si numai daca cineva chiar vrea ramura 2. ## Incident 16.09.2026 (2): ROMFAST 10.0.20.36, acelasi simptom Stare, nu concluzie. **Fapt.** Pe serverul Oracle de productie ROMFAST (`10.0.20.36`) actualizarea esueaza cu stiva `ORA-29273 / ORA-29024`, cu `PACK_UTILS` linia 313 si 305, `PACK_UPDATE` linia 323 si 180. **Fapt (masurat de pe statia de lucru, 16.09.2026).** `curl https://roa.romfast.ro/contafinupdate/roaupdate/` -> HTTP 200 in 0.127s; `curl http://10.0.20.122/` -> HTTP 404 in 0.0016s de la `Microsoft-HTTPAPI/2.0`. Al doilea e normal - situl real e pe portul 81, cu ruta `/contafinupdate/...`, iar 404-ul de la `http.sys` **nu** inseamna server picat. Deci serverul de update raspundea la ora verificarii. ### Cauza: `&` nu asteapta procesul sub jobul extern Configuratia era corecta: `POWERSHELLDOWNLOAD = 1`, `POWERSHELLTIMEOUT = 30`, `POWERSHELLPATH` completat, NTFS pe `C:\DMPDIR` cu `Authenticated Users:(M)`. `sys.ExecuteScriptOS` functiona - joburile `EXEC_PS_*` apar in `dba_scheduler_job_run_details` cu `SUCCEEDED`. **Sub jobul DBMS_SCHEDULER `job_type => 'executable'` (proces fara consola), operatorul `&` din PowerShell nu asteapta procesul nativ.** Masurat prin acelasi mecanism: ``` t0=23:07:08.671 t1=23:07:08.707 ec=[] exists=False <- la 36 ms dupa lansarea curl t2=23:07:13.735 exists=True <- dupa Start-Sleep 5 ``` Deci `$LASTEXITCODE` nu e niciodata setat, `if ($LASTEXITCODE -eq 0)` e FALSE (`$null -eq 0`), se executa ramura `else` pe un fisier inca inexistent, iar `curl` termina descarcarea dupa ce scriptul s-a incheiat si lasa `.part` pe disc definitiv. Fisierul destinatie nu apare niciodata -> polling-ul expira dupa `POWERSHELLTIMEOUT` -> `HTTPURITYPE` -> `ORA-29273 / ORA-29024`. Codul anterior scria cu `curl -o` direct in fisierul destinatie: neavand pas de redenumire, nu depindea de terminarea lui `curl`, iar bucla de polling astepta oricum aparitia fisierului. Pasul `Move-Item` introdus pe 16.09.2026 a facut ca asincronia sa conteze - de aceea simptomul apare la prima rulare de dupa recompilare. **Reparat** in `co_2026_09_16_06_COMUN_PACK_UTILS.sql`: lansarea asteapta explicit procesul si ii citeste codul de iesire. ```powershell $p = Start-Process -FilePath '' -ArgumentList '-k','-o','.part','' -Wait -PassThru -NoNewWindow if ($p.ExitCode -eq 0) { Move-Item ... } else { Remove-Item ... } ``` Dupa aplicare pe ROMFAST: `URL2Clob` intoarce documentul complet in ~2s, iar `PACK_UPDATE.UpdateROA` s-a incheiat cu `UPDATEROA_JOB` SUCCEEDED. **Ramas de verificat.** Capatul departat al db link-ului `DBL_ROMFAST2` este chiar `10.0.20.36`; la incidentul conpress s-a omorat sesiunea de pe partea apropiata (ROA_CENTRAL), fara sa se fi privit vreodata partea departata. Cele doua incidente pot avea radacini diferite - acesta nu il explica pe celalalt.