Diplomová prácaFRI UNIZA

Modulárny webový systém pre Katedru informatiky

Microservices platforma, ktorá spája nezávisle vyvíjané moduly do jedného katedrového portálu - od architektúry a integrácie cez automatizované nasadzovanie až po monitoring v produkcii.

uat.ki.fri.uniza.sk
Domovská obrazovka portálu Katedry informatiky
Modul
Identity Service running
Trace
POST /login · 142ms
trace_id: a3f8b2…
Event Bus
UserRegistered
{ "userId": "a83…" }

Prečo modulárny webový systém?

Existujúci portál Katedry informatiky bol roky iba statickou vizitkou - bez prihlásenia, bez správy obsahu, bez možnosti rozšírenia. Cieľom nebola len výmena vizuálu, ale postaviť platformu, ktorú možno rozširovať o nové moduly bez zásahu do jadra.

Modulárnosť

Nová funkčnosť vzniká ako samostatný modul. Každý modul je nezávislý - jeho pridanie či úprava sa nedotkne ostatných modulov ani jadra systému.

Centrálne prihlasovanie

Prihlasovanie cez univerzitné účty Microsoft Entra ID aj lokálne pozvánkové účty zabezpečuje jadro systému. Ostatné moduly tak autentifikáciu ani roly neriešia, len ich využívajú.

Pokračovanie

Projekt vznikol v rámci projektovej výučby a slúži ako základ, na ktorom môžu študenti v ďalších semestroch stavať vlastné rozširujúce moduly.

Ciele práce

Práca sa delí na dve oblasti: integrácia rieši, ako moduly spolupracujú, a orchestrácia, ako sa automatizovane dostanú na produkciu.

Integrácia modulov

Ako moduly spolupracujú

Návrh microservices architektúry a implementácia kľúčových modulov tak, aby boli technologicky nezávislé, no spoľahlivo spolupracovali - so spoločným prihlásením, dátami a udalosťami.

  • microservices
  • Microsoft Entra ID
  • RabbitMQ
  • gRPC
  • API gateway
Pozrieť architektúru
Orchestrácia modulov

Ako sa moduly dostanú na produkciu

Kontajnerizácia a CI/CD pipelines, ktoré automatizujú build, testy, doručenie na produkčné prostredia a sledovanie systému v reálnom čase.

  • Docker
  • GitHub Actions
  • OpenTelemetry
  • Grafana
  • Teams alerting
Pozrieť orchestráciu

Kľúčové časti systému

V rámci práce sú implementované tri moduly - správa používateľov, obsah katedrového portálu a študijné materiály. Dopĺňa ich zdieľaný servis, ktorý prináša sémantické vyhľadávanie naprieč celým systémom.

Identity

Jednotné prihlásenie a správa používateľov

Prihlásenie cez univerzitné účty (Microsoft Entra ID) aj lokálne účty na pozvánku. Správa používateľov a ich globálnych aj modulových rolí vrátane verejných profilov.

Portal

Obsah katedrového portálu

Aktuality s WYSIWYG editorom a podporou vyhľadávania, zoznam pracovníkov katedry synchronizovaný z LDAP, predmety a výskumné projekty.

Courses

Študijné materiály

Študijné materiály k predmetom usporiadané do kapitol. Ukazuje, ako sa do systému pridávajú nové rozširujúce moduly.

Zdieľaný servis

Sémantické vyhľadávanie naprieč modulmi

Používateľ nemusí poznať presné slová - stačí opísať, čo hľadá, a systém nájde obsah, ktorý zodpovedá významu jeho dotazu. V pozadí servis vytvára vektorové reprezentácie obsahu (embeddingy) cez lokálny ONNX model a ukladá ich do Qdrant DB. Takto ho využíva portál aj študijné materiály.

Text
Embedding
Qdrant
Výsledky

Architektúra systému

Pohľad na jednotlivé komponenty a ich vzťahy v rámci systému

scrollujte ďalej ↓
01 · POHĽAD ZHORA

Celý modulárny systém

Modulárny systém pozostáva z webového klienta, štyroch servisov, vlastných databáz a infraštruktúry pre messaging a observability. Servisy sú nasadené ako kontajnery cez Docker Compose.

02 · WEB CLIENT

Webová aplikácia

Jednotné používateľské rozhranie postavené v Angulari. So všetkými modulmi komunikuje cez Nginx API gateway, ktorý smeruje požiadavky na príslušné servisy - klient tak vystupuje ako jeden portál.

03 · IDENTITY MODUL

Centrálne prihlasovanie

IdentityService vydáva JWT tokeny podpísané RSA asymetrickou kryptografiou, spravuje globálne a modulové roly a publikuje udalosti o používateľoch cez Event Bus. Prepája systém s Microsoft Entra ID a FRI LDAP.

04 · PORTAL MODUL

Obsah katedrového portálu

PortalService spravuje aktuality, zamestnancov, predmety a výskumné projekty. Cez Event Bus si udržiava shadow tabuľku používateľov a synchronizuje pracovníkov z FRI LDAP.

05 · COURSES MODUL

Študijné materiály

Rozširujúci modul pre študijné materiály usporiadané do kapitol. Ukazuje, ako sa do systému pridávajú nové moduly - bez zásahu do jadra a ostatných modulov.

06 · SÉMANTICKÉ VYHĽADÁVANIE

Vector Indexer Service

Univerzálny servis pre generovanie embeddingov a sémantické vyhľadávanie - využíva lokálny ONNX model a Qdrant vektorovú databázu. Portal aj Courses ho používajú synchrónne cez gRPC pri vyhľadávaní v aktualitách a študijných materiáloch.

07 · INTERNÉ NÁSTROJE

Messaging a observability

RabbitMQ Management UI a Grafana Observability stack (Grafana + Loki + Tempo). Slúžia administrátorom na monitoring a vývojárom na diagnostiku - prístupné iba cez UNIZA VPN.

Vlastné NuGet knižnice

Dve vlastné knižnice používané naprieč .NET servismi systému.
Publikované cez GitHub Packages.

MIS.Mediator

in-process

Vlastná implementácia mediator patternu - oddeľuje API vrstvu od biznis logiky cez IMediator.SendAsync(). Vznikla ako náhrada za MediatR po zmene jeho licencie.

// Controller - IMediator cez DI (primary ctor)
public class ArticlesController(IMediator mediator)
    : ControllerBase
{
    [HttpGet("{slug}")]
    public async Task<IActionResult> Get(string slug)
    {
        var article = await mediator.SendAsync(
            new GetArticleQuery(slug));
        return Ok(article);
    }
}
// Request + handler (.Business projekt)
public record GetArticleQuery(string Slug)
    : IRequest<ArticleDto>;

public class GetArticleHandler(AppDbContext db)
    : IRequestHandler<GetArticleQuery, ArticleDto>
{
    public Task<ArticleDto> HandleAsync(
        GetArticleQuery q, CancellationToken ct)
    {
        // načítanie článku + mapovanie na ArticleDto
    }
}
// Program.cs
// AddMediator nájde a zaregistruje všetky
// IRequest + IRequestHandler v danom assembly
builder.Services.AddMediator(
    typeof(GetArticleQuery).Assembly);

MIS.EventBus

cross-service

Abstrakcia nad RabbitMQ - jeden servis udalosti publikuje, iné ich konzumujú, pričom o detaily komunikácie s message brokerom sa stará knižnica. Servisy tak medzi sebou komunikujú asynchrónne.

// IdentityService - IEventBus cez DI
public class AuthService(IEventBus eventBus)
{
    public async Task Register(UserProfile user)
    {
        // ... uloženie používateľa
        await eventBus.Publish(
            new UserRegisteredEvent(user));
    }
}
// Event + consumer (PortalService)
[Exchange(prefix: "IdentityService")]
public record UserRegisteredEvent(UserProfile User);

public class UserRegisteredConsumer(AppDbContext db)
    : IConsumer<UserRegisteredEvent>
{
    public Task Consume(UserRegisteredEvent msg)
    {
        // synchronizácia shadow tabuľky
    }
}
// Program.cs
// AddEventBus pripojí RabbitMQ a auto-registruje
// všetky IConsumer<T> v danom assembly
builder.Services.AddEventBus(
    typeof(UserRegisteredConsumer).Assembly);

Od integrácie k orchestrácii

Hotový systém je potrebné po vývoji spoľahlivo doručiť na produkčné prostredie pre koncových používateľov a následne monitorovať prevádzku, aby sa včas zachytili prípadné chyby. Druhá oblasť práce automatizuje tieto fázy - od zmien v kóde až po upozornenia o chybách.

Zdrojové kódy v GitHub organizácii

Systém je rozdelený do repozitárov podľa modulov, sústredených v jednej privátnej GitHub organizácii - celý tím tak má na jednom mieste prehľad o všetkých častiach systému a o ich existencii. Každý repozitár má vlastné CI/CD pipeliny, citlivé údaje sú vďaka GitHub Secrets držané mimo kódu a vlastné knižnice sa publikujú do privátneho NuGet feedu cez GitHub Packages.

mis-platform

Jadro

WebClient, IdentityService, PortalService a infraštruktúra - RabbitMQ a Grafana stack. Servisy jadra sa nasadzujú spolu.

mis-courses-module

Modul

CoursesService - modul študijných materiálov. Demonštruje, ako sa systém rozšíri o nezávisle nasaditeľný modul.

mis-vector-indexer-service

Servis

VectorIndexerService - interný gRPC servis pre sémantické vyhľadávanie (embedding cez ONNX + Qdrant). Nepatrí žiadnemu modulu.

mis-mediator-lib

Knižnica

NuGet balík MIS.Mediator - in-process CQRS mediator. Publikovaný do GitHub Packages.

mis-eventbus-lib

Knižnica

NuGet balík MIS.EventBus - abstrakcia nad RabbitMQ. Publikovaný do GitHub Packages.

mis-sample-module

Šablóna

Kostra pre tvorbu nových modulov - pripravená štruktúra, konfigurácia a pipeliny na štart.

mis-docs

Dokumentácia

Interná technická dokumentácia pre celý vývojový tím - architektúra, onboarding nových členov, konvencie a postupy pri integrácii modulov.

replace-tokens-action

GitHub Action

Vlastná GitHub Action - počas nasadzovania nahradí placeholdery v .env reálnymi hodnotami zo Secrets.

Automatizované CI/CD pipeliny

Štyri typy GitHub Actions workflows automatizujú validáciu zmien, nasadzovanie do produkcie, databázové migrácie a publikovanie nových verzií vlastných knižníc.

PR Validation

Automaticky pri PR
  • Validačný build
  • Unit testy (xUnit)
  • Integračné testy (Testcontainers)
  • Výsledky späť do Pull Requestu

Release to Production

Manuálne spustenie
  • Build Docker obrazu s tagom verzie
  • Náhrada secretov a nasadenie
  • Overenie cez Health Check
  • Automatický GitHub Release

Migrate DB Production

Manuálne spustenie
  • Build obrazu s EF Bundle
  • Aplikovanie migrácií schémy na produkčnú DB
  • Podpora rollbacku migrácie

Publish NuGet Package

Manuálne spustenie
  • Build & publish .nupkg
  • Odoslanie do GitHub Packages
  • Automatický GitHub Release
Hlavná pipelina

Release to Production - reťazec štyroch jobov

Manuálne spustenie cez GitHub UI rozbehne štyri na seba nadväzujúce joby. Build (ci) aj deploy (cd) sú vyčlenené do znova použiteľných workflowov, takže sa dajú spustiť aj samostatne.

1 version
  • Výpočet verzie vYY.MM.DD.N
  • z dátumu + poradia releasov daného dňa
2 ci · build reusable
  • Náhrada build secretov
  • docker compose build
  • Otagovanie obrazov verziou
3 cd · deploy reusable
  • Náhrada secretov do .env (replace-tokens-action)
  • Kopírovanie compose & .env na server
  • docker compose up
  • Health Check /health
4 release
  • GitHub Release s tagom verzie
  • Auto-generované poznámky (PRs od posledného releasu)

Beží na self-hosted runneri - build aj deploy na tom istom serveri.

Monitoring cez Grafana observability stack

Každý servis posiela logy a distribuované traces cez OpenTelemetry do centrálneho monitorovacieho systému. Detail tracu ukáže, ktorými servismi požiadavka prešla. Vďaka korelácii cez Trace ID sa k danému tracu zobrazia len súvisiace logy.

Grafana Loki Tempo OpenTelemetry
Trace · prihlásenie cez Microsoft Entra ID trace_id: a3f8b2…
IdentityService · POST login.microsoftonline.com 54 ms
Identity DB · overenie používateľa 12 ms
Identity DB · načítanie LDAP kópie 11 ms
Identity DB · vloženie používateľa 13 ms
Event Bus · publikovanie UserRegisteredEvent 7 ms
PortalService · sync shadow tabuľky 18 ms
CoursesService · sync shadow tabuľky 16 ms
Identity DB · uloženie Refresh Tokenu 13 ms
IdentityService Identity DB Event Bus PortalService CoursesService

Jedna požiadavka, jeden Trace ID - naprieč všetkými servismi.

V Grafana dashboarde stačí kliknúť na požiadavku zo zoznamu tracov a zobrazí sa jej timeline so spanmi aj všetky súvisiace logy skorelované podľa Trace ID. To výrazne uľahčuje hľadanie príčin chýb v distribuovanom systéme.

  • Zoznam tracov zo všetkých servisov
  • Timeline spanov vybraného tracu
  • Logy skorelované podľa Trace ID

Real-time alerting cez Microsoft Teams

Pri error logu Grafana automaticky upozorní administrátorov. Cez Power Automate webhook príde do Teamsu notifikácia so zoznamom chýb a tlačidlom priamo na trace v Grafane.

  1. Error log servis zaloguje chybu (log level error)
  2. Grafana alert rule zachytí error log a odošle ho ako Adaptive Card (JSON) na Power Automate
  3. Power Automate webhook flow publikuje prijatú správu do Teamsu
  4. Teams Group Chat notifikácia v reálnom čase
Chyba v produkcii
IdentityService14:32:08
Unhandled exception: LDAP connection timeout
PortalService14:32:09
Failed to consume UserRegisteredEvent
Otvoriť trace v Grafane

Ukážka systému

Vybrané ukážky funkcií nasadeného systému, zoskupené podľa modulov.
Ukážky zachytávajú stav systému v čase obhajoby práce.

Dominik Ježík Diplomová práca - Modulárny webový systém

Ing. Dominik Ježík

Software Engineer

Som absolvent Fakulty riadenia a informatiky na Žilinskej univerzite v Žiline, kde som obhájil diplomovú prácu na tému Modulárny webový systém - integrácia a orchestrácia modulov.

Vďaka nej som získal cenné skúsenosti nielen s vývojom, ale najmä so system designom a architektonickými rozhodnutiami na úrovni celého systému - od návrhu microservices architektúry cez automatizovaný deployment až po monitoring a alerting v produkcii. Tento pohľad na softvér ako celok ma baví a motivuje posúvať sa ďalej.

V minulosti som obhájil aj bakalársku prácu na tému Webová časť systému First Responder.