Egy régi alkalmazás modernizálása

2020.03.21.

Volt lehetőségem részt venni egy izgalmas projectben, ahol egy régi desktop alkalmazást írtunk újra webes verzióra. Most megismerheted, milyen alapelvek szerint modernizáltuk ezt az eszközt.

A program története

Valamikor a 2000-es évek elején még leginkább natív appokat írtak cégek számára, mikor egyedi, vagy közel egyedi megoldásokra volt szükségük. Alanyunk egy nyilvántartás (szándékosan nem írom le a konkrét termék nevét), amit dobozosként kínáltak, de volt lehetőség benne egyedi modulok megrendelésére is. A fejlesztő cég azóta már nincs meg, így az utolsó verzió állt rendelkezésünkre. Delphi, Visual Basic, esetleg .Net korai verziók, ezek voltak a kor technológiái, igazából mindegy is, miben írták, mert nincs forrás, egy fekete dobozunk van. Ami előny, hogy SQL adatbázist használ, így azt lehet exportálni, tanulmányozni a táblaszerkezetet.

Milyen adatbázist választottunk?

Ami feltűnt a modernizáló csapatnak, hogy a legtöbb adat olyan, amit inkább tennénk dokumentum alapú adatbázisba, mint SQL-be. Amikor ezt írták, akkor még nem igazán volt olyan. Tehát adta magát, hogy legyen MongoDB. Volt benne tapasztalata mindenkinek.

mongodb logo

Mi lesz a programozási nyelv?

Lehetne hitvitát csinálni ebből, de az a helyzet, hogy a feladat és a környezet fogja meghatározni, miben írjuk meg. Az adatbázis már ugye eldöntött tény. A program működését vizsgálva több olyan funkciót is találtunk, amit aszinkron módon lehetne alkalmazni, és persze volt jó pár olyan, aminél a websocket használata is növelné a felhasználói élményt. Szerintem innentől minden fejlesztő kórusban vágja rá, hogy NodeJS.

nodejs logo

Core, vagy keretrendszer?

Van egy csomó olyan funkció, amit nem érdemes leprogramozni újból, mert annyira egyszerű a működése, hogy abból hatékonyabbat már nem biztos hogy tudunk készíteni. Ez egy elég súlyos érv egy legalább alap keretrendszer mellett. Mi szól még mellette? A konvenciók nagy része le van fektetve már eleve, tehát belekényszeríti a fejlesztőt egy fix struktúrába. Ami gondolkodásra adhat okot, hogy mit használjunk. Számtalan keret áll rendelkezésre, és nem biztos, hogy a legnépszerűbb lesz tökéletes választás.

total.js logo

Szóval mindenki bedobta javaslatát és megvizslattuk azokat. Végül nyert az, amit javasoltam: Total.js. Olyan 2015 óta használom. Tulajdonsága, hogy a core libeken kívül nincs más függősége, és mégis megvalósít rengeteg hasznos funkciót. Struktúrája jól kialakított, átlátható, érthető, de mégis rugalmas, rengeteg alternatívát kínál már önmagában is. Fontos szempont volt az, hogy a keretprogramban csak az alap funkciókat terveztük implementálni (felhasználókezelés, authentikáció, stb.), minden egyéb funkciót modulként terveztünk bele. Ezt a Total.js-el tökéletesen meg lehet oldani, több lehetőséget is kínál rá.

Kiegészítő függőségek

Az nem kérdés, hogy ha skálázni szeretnénk, akkor a sessionöket jó lenne valahogy központilag kezelni. És persze szeretnénk szabadszavas keresést is. A keretrendszer bár kínál alapvető kulcs-érték páros cache-t, de ezt elvetettük a skálázhatóság miatt. Nyilván a Redis lett a befutó. Van neki egy jó kis modulja, a RediSearch, amivel a keresés is kialakítható (ráadásul létezik konténerben összeállítva is). A feladathoz bőven elég, nem kell mondjuk Elasticot odatennünk, és szintén dolgozott már vele mindenki (nekem is van aktív projectem, amiben használom).

redisearch logo

Frontend

No itt már volt némi vita. A program iszonyú egyszerű felületét tekintve, nem szükséges agyongondolni. Nem is volt dedikált frontendes emiatt a projectben (de tényleg, nincs dashboard, nincs csicsa, egyszerű formok, táblázatok). Semantic UI lett végül a befutó, egyszerűen lehet vele dolgozni, alapvetően modern külsőt kölcsönöz, és tartalmaz minden olyan elemet, amire szükségünk van. Statisztikákhoz Chart.js lett a választott, a készlete tökéletesen kielégítő a feladathoz.

A fejlesztői környezet

Igyekeztünk mindenben egységesek lenni. Így már eleve dockerben dolgoztunk (ajánlom Soós Gábor cikksorozatát a témáról), és mindenkinek elérhetővé tettünk egy teszt adatbázis exportot, amit aztán a saját gépén fel tudott csatolni a mongo konténerébe. Ajánlás volt, de nem volt kötelező a Microsoft Visual Studio Code szerkesztője, amiben számos plugin segítette a munkát.

gogs.io logo

A kód tárolására a Gogs gitszervert használtuk. A Gitlab esetünkben ágyúval verébre lett volna. Tud felhasználókat és jogokat kezelni, tud webhookra küldeni, és ezáltal integrálható volt a Drone CI-ba.

Ugyanis ezt választotta a csapat. Én ekkor találkoztam a Drone-al először, és annyira megtetszett, hogy azóta több projectemben is lecseréltem a Jenkinst. Nem kell előre telepíteni plugineket, ha használni akarjuk, hanem elég felvenni a reponkban letett .drone.yml fájlunkba a folyamatot, és a szerver ezt majd docker konténerekkel röptében megoldja. Tehát például ha valakinek egy adott modul fejlesztésénél szüksége van a SonarQube-ra a project standardjétől eltérő beállításokkal, akkor anélkül kísérletezhet vele, hogy teleszemetelné a fő ágat (mert ugye minden alkalommal önálló konténerrel operál). Ötletes és hatékony megoldás.

A Drone csinálja a végén a kész image-et is a privát registrybe, így egészen jól minimalizálni lehetett a teljes folyamat szoftverigényét.

Hogyan kapja meg az ügyfél?

Volt a megrendelőtől egy olyan igény, hogy SaaS-ként is lehessen a szolgáltatást értékesíteni, de lehessen az ügyfelek saját infrastruktúráján is futtatni anélkül, hogy meg kéne tanulniuk egy Boeing műszerfalát. Az appot eleve úgy terveztük, hogy dockeren kívül is aránylag kis energiabefektetéssel be lehessen üzemelni.

A docker alapvetően adott tehát, hiszen abban indult a fejlesztés. Emellé készítettünk egy Ansible playbookot és docker-compose állományt is, így előállt egy olyan csomag, amivel valóban „one click install” lett az egész. Ha van egy alap OS egy VM-en, akkor a playbook elintéz mindent, még a compose-t is elindítja, ha dockeres futtatást választjuk. De a usernek lehetősége van már meglévő docker rendszerben is elindítani azt a compose-al, vagy annak példája alapján más felépítményben is.

Azt pedig gondolom mondanom sem kell, hogy kaptak kész megoldást az adatmigrációra is.

Konklúzió

Csapatban dolgozni jó, de fontos, hogy a csapat akként is viselkedjen. Tudjunk engedni a saját „igazunkból”, és ne legyünk restek új eszközöket kipróbálni. Nem mindig a megszokott receptekkel érdemes operálni. Előfordulhat, hogy akár csak egy Git esetén is jobb választás lehet az adott project életében egy pehelysúlyúbb eszköz, de igaz ez akár a CI-ra is (ami talán a legnagyobb szellemi profitom ebből a munkából). Mindig törekedj a projecthez mérten legegyszerűbb megoldásra, ne nehezítsd meg feleslegesen az életedet. Nyilván ne csorbuljon semmi, de vizsgáld meg, hogy van-e hatékonyabb eszköz a célhoz.

Fontos tanulságnak tartom azt is, hogy a régi programok nem feltétlen rosszak, csak lehet, hogy érdemes őket felújítani/újraépíteni. Nem mindenre van kész megoldás, nem mindent lehet helyettesíteni (egy magyar jogszabálynak megfelelőséget egy cloudban bérelhető, de más nemzet által kialakított eszköz nem fogja teljesíteni maradéktalanul). Viszont lehet modern eszközökkel olyan appot tervezni, ami folyamatos karbantartás mellet jó pár évig hasznos szoftvere lesz az adott ügyfélkörnek.