diff --git a/README.md b/README.md
index f5b8ee5..2f07d4b 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# BMEVIAUBC01 Szoftverfejlesztés laboratórium
-Labor feladatok:
+Laborfeladatok:
- [MSSQL szerver oldali programozás](mssql/README.md)
- [MSSQL Reporting Services](reportingservices/README.md)
diff --git a/spring-cloud/Feladat-1.md b/spring-cloud/Feladat-1.md
index e907237..443a4bd 100644
--- a/spring-cloud/Feladat-1.md
+++ b/spring-cloud/Feladat-1.md
@@ -1,31 +1,45 @@
-# 1. Feladat: Config server
+# 1. feladat: Config server
-Indítsd el a currency alkalmazást, majd a bonus alkalmazást (Pl. jobb klikk > Run as... > Spring Boot App). Azt tapasztalod, hogy az egyik nem fog elindulni, mert mindkettő a default 8080-as porton szeretne elindulni, és a korábban elinduló már elfoglalja ezt a portot.
+Indítsd el a `CurrencyApplication`-t, majd a `BonusApplication`-t (Pl. jobb klikk > _Run as..._ > _Spring Boot App_).
+Azt tapasztalod, hogy az egyik nem fog elindulni, mert mindkettő a default `8080`-as portot szeretné használni, de a
+korábban elinduló már elfoglalta.
-Az egy gépen történő futtatáshoz mindenképp külön portot kell beállítani az alkalmazásoknak. A booking projektben lévő src\main\application.proprerties ben látható is, hogy server.port=9080, így ez nem akadna össze a többivel.
+Az egy gépen történő futtatáshoz mindenképp külön portot kell beállítani az alkalmazásoknak. A `booking` projektben lévő
+`src\main\application.proprerties`-ben látható is, hogy `server.port=9080`, így ez nem akadna össze a többivel.
-De a légitársaság a belső szolgáltatásait nem az egyes alkalmazások belső konfig fájljaiban akarja konfigurálni, hanem egy központosított helyen, ezért egy konfig szervert fog bevezetni. A konfig szerver egy külön alkalmazás lesz (a neve pl. *config*), amelyeknek a bonus, currency és flights alkalmazások a kliensei lesznek, vagyis ettől fogják lekérdezni induláskor a saját konfigurációjukat. A Spring Cloud Config projekt beépítve tartalmaz támogatást a szerver és a kliens oldalhoz is, amit az alábbi módon vehetünk igénybe:
+De a légitársaság a belső szolgáltatásait nem az egyes alkalmazások belső konfigfájljaiban akarja konfigurálni, hanem
+egy központosított helyen, ezért egy konfigszervert fog bevezetni. A konfigszerver egy külön alkalmazás lesz (a neve pl.
+`config`), amelyeknek a `bonus`, `currency` és `flights` alkalmazások a kliensei lesznek, vagyis ettől fogják lekérdezni
+induláskor a saját konfigurációjukat. A Spring Cloud Config projekt beépítve tartalmaz támogatást a szerver- és a
+kliensoldalhoz is, amit az alábbi módon vehetünk igénybe:
-1. Hozz létre egy új projektet, *config* néven. Ha STS-t használsz, a leggyorsabb ezt a File > New > Spring Starter Project menüből indítani. 17-es Java-t és Mavent válassz a varázsló első oldalán, majd a második oldalon a választható függőségek közül a Spring Cloud Config csoport alatt a Config Server-t.
+1. Hozz létre egy új projektet `config` néven. Ha STS-t használsz, a leggyorsabb ezt a _File_ > _New_ > _Spring Starter
+ Project_ menüből indítani. 17-es Javát és Mavent válassz a varázsló első oldalán, majd a második oldalon a
+ választható függőségek közül a Spring Cloud Config csoport alatt a Config Servert.
-2. Vizsgáld meg a keletkező pom.xml-t. Látható, hogy a parent projekt ugyanúgy a spring-boot-parent, ahogy azt megszoktuk. Viszont létrejött egy dependencyManagement tag, amely a spring cloud-os függőségeket húzza be. (Az aktuális Spring Cloud verzió a 2023.0.3, ami property-be van kiszervezve):
+2. Vizsgáld meg a keletkező `pom.xml`-t. Látható, hogy a parent projekt ugyanúgy a `spring-boot(-starter)-parent`, ahogy
+ azt megszoktuk. Viszont létrejött egy `dependencyManagement` tag, amely a spring cloud-os függőségeket húzza be. (Az
+ aktuális Spring Cloud verzió a 2023.0.3, ami propertybe van kiszervezve):
- ```
+ ```xml
-
-
- org.springframework.cloud
- spring-cloud-dependencies
- ${spring-cloud.version}
- pom
- import
-
-
+
+
+ org.springframework.cloud
+ spring-cloud-dependencies
+ ${spring-cloud.version}
+ pom
+ import
+
+
```
- A dependencyManagement tag nem összekeverendő a dependencies taggel! Ha egy konkrét Spring cloud-os függőséget ténylegesen használni akarunk, akkor azt a dependencies tagbe kell tenni, persze a verziót elhagyhatjuk, mert azt megkapjuk a dependencyManagement tagből:
- ```
+ A `dependencyManagement` tag nem összekeverendő a `dependencies` taggel! Ha egy konkrét Spring cloud-os függőséget
+ ténylegesen használni akarunk, akkor azt a `dependencies` tagbe kell tenni, persze a verziót elhagyhatjuk, mert azt
+ megkapjuk a `dependencyManagement` tagből:
+
+ ```xml
org.springframework.cloud
@@ -35,11 +49,11 @@ De a légitársaság a belső szolgáltatásait nem az egyes alkalmazások bels
```
-
-3. A varázsló létrehozott egy application.properties fájlt, de mi yml formában konfiguljuk az alkalamzásunkat, ezért hozzunk létre egy application.yml fájlt az src\main\resources alatt. Ebbe az alábbi tartalom kerüljön:
+3. A varázsló létrehozott egy `application.properties` fájlt, de mi YAML formátumban konfiguráljuk az alkalmazásunkat,
+ ezért hozzunk létre egy `application.yaml` fájlt az `src\main\resources` alatt. Ebbe az alábbi tartalom kerüljön:
- ```
+ ```yaml
server:
port: 8081
spring:
@@ -54,86 +68,112 @@ De a légitársaság a belső szolgáltatásait nem az egyes alkalmazások bels
search-locations: classpath:/config
```
- A konfig eleje értelemszerűen a config szerver portját állítja 8081-re. Az alkalmazás neve az lesz, hogy *config*, majd bekapcsoljuk a "native" profile-t. Ennek hatására a config szerver nem egy git repoból próbálja majd olvasni a konfig fájlokat (ami amúgy valós környezetben hasznos lehetne), hanem lokális fájlrendszerből. Hogy pontosan honnan, azt a következő konfig adja meg: a classpath config könyvtárából.
-
-4. Hozzuk létre az src\main\resources alatt a config könyvtárat, abban pedig 3 yml fájlt: bonus.yml, flights.yml, currency.yml. Ezekben konfigoljunk nem ütköző portokat a három alkalmazásnak. A currency.yml-ben pedig ezen felül még az átváltási jutalékot is állítsuk 1.5 %-ra:
+ A konfig eleje értelemszerűen a config szerver portját állítja `8081`-re. Az alkalmazás neve az lesz, hogy `config`,
+ majd bekapcsoljuk a `native` profile-t. Ennek hatására a config szerver nem egy Git repóból próbálja majd olvasni a
+ konfigfájlokat (ami amúgy valós környezetben hasznos lehetne), hanem lokális fájlrendszerből. Hogy pontosan honnan,
+ azt a következő konfig adja meg: a `classpath` `config` könyvtárából.
- ```
+4. Hozzuk létre az `src\main\resources` alatt a `config` könyvtárat, abban pedig 3 YAML fájlt: `bonus.yaml`,
+ `flights.yaml`, `currency.yaml`. Ezekben konfigoljunk nem ütköző portokat a három alkalmazásnak:
+ ```yaml
server:
port: 8083
- currency:
- exchangePremium: 0.015
```
-5. A config projekt main osztályára (ConfigApplication) tegyük rá a *@EnableConfigServer* annotációt, ezzel a konfig szerver elkészült.
-
-6. Most a három légitársasági alkalmazást állítjuk be, hogy a konfig szervert konfig kliensként használják. Az alábbi lépéseket mindháromra (bonus, currency, flights) végezzük el.
-
- - A pom.xml-ben:
-
- - A <properties> tagbe helyezzük el ezt a sort:
-
- ```
- 2023.0.3
- ```
-
- - A <properties> tag alá helyezzük el ezeket a sorokat:
-
- ```
-
-
-
- org.springframework.cloud
- spring-cloud-dependencies
- ${spring-cloud.version}
- pom
- import
-
-
-
- ```
-
- - A spring-boot-starter-web függőség után illesszük be ezeket a sorokat:
-
- ```
-
- org.springframework.cloud
- spring-cloud-starter-config
-
- ```
-
- - Hozzuk létre a application.properties fájlt az src\main\resources alatt, ezzel a tartalommal (a *name* utáni érték értelemszerűen az adott projektnek megfelelő legyen):
-
- ```
- spring.application.name=bonus
- spring.config.import=optional:configserver:http://localhost:8081
- ```
-
- - Megjegyzések:
- - A fenti két propertyt application.yml-ben is megadhatnánk. A currency projektben pl. már eleve application.yml fájlunk van, amiben az átváltási jutalékot definiáljuk. Kiegészíthettő lenne tehát ilyen módon:
- ```
- currency:
- exchangePremium: 0.01
- spring:
- application:
- name: currency
- config:
- import: optional:configserver:http://localhost:8081
- ```
- - Az optional: prefix azt szolgálja, hogy az alkalmazásunk akkor is el tudjon indulni, ha a konfig szerver nem elérhető. Ha azonban ez előfordulna, visszajutnánk a kezdeti problémához: a default 8080-as porton akarna elindulni minden alkalmazás. Tehát a helyes működéshez a config szervert kell majd először elindítani.
- - Ha nem tudjuk vagy akarjuk biztosítani, hogy a config szerver induljon el először, az alkalmazásokat beállíthatjuk úgy is, hogy induláskor többször próbálkozzanak a config szerver elérésével, erről itt olvashatók részletek: https://docs.spring.io/spring-cloud-config/docs/current/reference/html/#config-client-retry
- - A Spring Boot 2.4 vezette be a spring.config.import property-t, amivel a fenti módon, egyszerűen lehet máshonnan (jelen esetben egy config szerverről) konfigurációt importálni. Korábbi verziókban egy bootstrap.yml fájlra volt szükség, ott kellett megadni az alkalmazás nevét és a config szerver elérhetőségét (a spring.cloud.config.uri property-ben). Ha a régi módon, a bootstrap.yml-t akarnánk használni, a spring.cloud.bootstrap.enabled=true property-vel, vagy a spring-cloud-starter-bootstrap függőség behúzásával tudnánk megtenni.
-
-7. Indítsd el a config alkalmazást, majd sorban a bonus, currency és flights alkalmazásokat! Jól használható erre a célra a bal alsó sarokban lévő Boot Dashboard nézet, ahol gyorsan kiválasztható bármelyik alkalmazás, ami után egyszerű vagy debug módú futtatás kezdeményezhető a megfelelő ikonnal. (Ha már fut az alkalmazás, akkor először le is állítja azt, így nem kell portütközéstől tartani. A *-api projekteket értelemszerűen nem lehet elindítani, mert nincs bennük main osztály.)
+ - A `currency.yaml`-ben pedig ezen felül még az átváltási jutalékot is állítsuk 1,5%-ra:
+
+ ```yaml
+ currency:
+ exchangePremium: 0.015
+ ```
+
+5. A `config` projekt main osztályára (`ConfigApplication`) tegyük rá a `@EnableConfigServer` annotációt, ezzel a
+ konfigszerver elkészült.
+
+6. Most a három légitársasági alkalmazást állítjsk be, hogy a konfigszervert konfigkliensként használják. Az alábbi
+ lépéseket mindháromra (`bonus`, `currency`, `flights`) végezzük el.
+
+ - A `pom.xml`-ben:
+
+ - A `` tagbe helyezzük el ezt a sort:
+
+ ```xml
+ 2023.0.3
+ ```
+
+ - A `` tag alá helyezzük el ezeket a sorokat:
+
+ ```xml
+
+
+
+ org.springframework.cloud
+ spring-cloud-dependencies
+ ${spring-cloud.version}
+ pom
+ import
+
+
+
+ ```
+
+ - A `spring-boot-starter-web` függőség után illesszük be ezeket a sorokat:
+
+ ```xml
+
+ org.springframework.cloud
+ spring-cloud-starter-config
+
+ ```
+
+ - Adjuk hozzá az `application.properties` fájlhoz (`src\main\resources`) ezeket (a `name` utáni érték értelemszerűen
+ az adott projektnek megfelelő legyen):
+
+ ```
+ spring.application.name=bonus
+ spring.config.import=optional:configserver:http://localhost:8081
+ ```
+
+ - A `currency` projektben `application.yml` fájlunk van, amiben az átváltási jutalékot definiáljuk. Egészítsük
+ ki ezzel:
+ ```yaml
+ currency:
+ exchangePremium: 0.01
+ spring:
+ application:
+ name: currency
+ config:
+ import: optional:configserver:http://localhost:8081
+ ```
+ - Az `optional:` prefix azt szolgálja, hogy az alkalmazásunk akkor is el tudjon indulni, ha a konfigszerver
+ nem elérhető. Ha azonban ez előfordulna, visszajutnánk a kezdeti problémához: a default `8080`-as porton
+ akarna elindulni minden alkalmazás. Tehát a helyes működéshez a konfigszervert kell majd először
+ elindítani.
+ - Ha nem tudjuk vagy akarjuk biztosítani, hogy a konfigszerver induljon el először, az alkalmazásokat
+ beállíthatjuk úgy is, hogy induláskor többször próbálkozzanak a konfigszerver elérésével, erről itt
+ olvashatóak
+ részletek: https://docs.spring.io/spring-cloud-config/docs/current/reference/html/#config-client-retry
+ - A Spring Boot 2.4 vezette be a `spring.config.import` propertyt, amivel a fenti módon, egyszerűen lehet
+ máshonnan (jelen esetben egy konfigszerverről) konfigurációt importálni. Korábbi verziókban egy
+ `bootstrap.yml` fájlra volt szükség, ott kellett megadni az alkalmazás nevét és a konfigszerver
+ elérhetőségét (a `spring.cloud.config.uri` propertyben). Ha a régi módon, a `bootstrap.yml`-t akarnánk
+ használni, a `spring.cloud.bootstrap.enabled=true` propertyvel, vagy a `spring-cloud-starter-bootstrap`
+ függőség behúzásával tudnánk megtenni.
+
+7. Indítsd el a `ConfigApplication`-t, majd sorban a `BonusApplication`-t, `CurrencyApplication`-t és
+ `FlightsApplication`-t! Jól használható erre a célra a bal alsó sarokban lévő Boot Dashboard nézet, ahol gyorsan
+ kiválasztható bármelyik alkalmazás, ami után egyszerű vagy debug módú futtatás kezdeményezhető a megfelelő ikonnal. (
+ Ha már fut az alkalmazás, akkor először le is állítja azt, így nem kell portütközéstől tartani. A `*-api` projekteket
+ értelemszerűen nem lehet elindítani, mert nincs bennük main osztály.)

8. Készíts két képernyőképet a jegyzőkönyvbe:
- 1. Az elsőn látszódjon a currency.yml megnyitva az IDE-ben, és mellette egy böngészőben az átváltó API meghívásának eredménye, USD -> HUF irány esetére
- 2. A másodikon látszódjon a bonus.yml megnyitva az IDE-ben, és mellette egy böngészőben a saját NEPTUN kódodnak megfelelelő user bonusának lekérdezése
-
-
+ 1. Látszódjon a `currency.yaml` megnyitva az IDE-ben, és mellette egy böngészőben az átváltó API meghívásának
+ eredménye, USD -> HUF irány esetére
+ 2. Látszódjon a `bonus.yaml` megnyitva az IDE-ben, és mellette egy böngészőben a saját Neptun-kódodnak megfelelelő
+ user bonusának lekérdezése
## Következő feladat
diff --git a/spring-cloud/Feladat-2.md b/spring-cloud/Feladat-2.md
index cd4c83c..3e1f14e 100644
--- a/spring-cloud/Feladat-2.md
+++ b/spring-cloud/Feladat-2.md
@@ -1,21 +1,30 @@
-# 2. Feladat: Discovery server
+# 2. feladat: Discovery server
-Egy microservice architektúrában célszerű egy discovery szerveren nyilvántartani, hogy melyik szolgáltatás milyen címen, vagy ha több példányban futtatjuk őket, akkor milyen cím**ek**en elérhető. Így pl. a kliensekbe nem kell beégetni a szolgáltatások címeit, és ha valamelyik szolgáltatást áthelyezik másik szerverre, a kliensek automatikusan megtalálják az új címet. Vagy ha címen elérhető egy szolgáltatás, akár terheléselosztó logikát is tehetünk a discovery mechanizmusba. Most ezt fogjuk megvalósítani, szintén Spring Cloud támogatással.
+Egy microservice architektúrában célszerű egy discovery serveren nyilvántartani, hogy melyik szolgáltatás milyen címen,
+vagy ha több példányban futtatjuk őket, akkor milyen cím**ek**en elérhető. Így pl. a kliensekbe nem kell beégetni a
+szolgáltatások címeit, és ha valamelyik szolgáltatást áthelyezik másik szerverre, a kliensek automatikusan megtalálják
+az új címet. Vagy ha címen elérhető egy szolgáltatás, akár terheléselosztó logikát is tehetünk a discovery
+mechanizmusba. Most ezt fogjuk megvalósítani, szintén Spring Cloud támogatással.
-1. Hozzuk létre a discovery szerver projektjét, Ismét célszerű a File > New > Spring Starter Project varázslót használni. A projekt neve legyen *discovery*. A következő oldalon a lehetséges függőségek közül válasszuk a Spring Cloud Discovery csoportból az Eureka Server-t és a Spring Cloud Config csoportból a Config Client-et. (Maga a discovery szerver is a config szerverről fogja venni a saját konfigját.)
+1. Hozzuk létre a discovery server projektjét! Ismét célszerű a _File_ > _New_ > _Spring Starter Project_ varázslót
+ használni. A projekt neve legyen `discovery`. A következő oldalon a lehetséges függőségek közül válasszuk a Spring
+ Cloud Discovery csoportból az Eureka Server-t és a Spring Cloud Config csoportból a Config Client-et. (Maga a
+ discovery szerver is a config szerverről fogja venni a saját konfigját.)
-2. A konfig szerver beállításához hozzuk létre az src\main\resources alá az application.properties fájlt, a szokásos tartalommal:
+2. A konfig szerver beállításához hozzuk létre az `src\main\resources` alá az `application.properties` fájlt a szokásos
+ tartalommal:
```
spring.application.name=discovery
spring.config.import=optional:configserver:http://localhost:8081
```
-
-3. A main osztályra (DiscoveryApplication) tegyük rá az *@EnableEurekaServer* annotációt.
-4. A config projektben lévő src\main\resources\config könyvtár alá hozzuk létre a neki megfelelő konfig fájlt discovery.yml néven, az alábbi tartalommal:
+3. A main osztályra (`DiscoveryApplication`) tegyük rá az `@EnableEurekaServer` annotációt.
- ```
+4. A config projektben lévő `src\main\resources\config` könyvtár alá hozzuk létre a neki megfelelő konfig fájlt
+ `discovery.yaml` néven az alábbi tartalommal:
+
+ ```yaml
server:
port: 8085
eureka:
@@ -28,29 +37,41 @@ Egy microservice architektúrában célszerű egy discovery szerveren nyilvánta
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
```
- Ha a 8085-ös portot már elhasználtad valamelyik korábbi alkalmazásra, akkor értelemszerűen itt mást kell megadnod. A Spring Cloud több discovery megoldást is támogat, mi most az Eureka-t használjuk, amely egy Netflix fejlesztés springes adoptációja. Az Eureka a beregisztrált szolgáltatásokat nem DB-ben tárolja, hanem memóriában, de a hibatűrés érdekében az Eureka szerver példányok egymás közt replikálják az adataikat. Ezen kívül az Eureka kliensek szintén cache-elik a kereséseik eredményét, így jó hibatűrés jellemzi a megoldást. Mi most egyetlen eureka szervert fogunk futtatni, így a konfigban azt állítottuk be, hogy ne próbáljon más Eureka szerverekkel kommunikálni.
+ Ha a 8085-ös portot már elhasználtad valamelyik korábbi alkalmazásra, akkor értelemszerűen itt mást kell megadnod. A
+ Spring Cloud több discovery megoldást is támogat, mi most az Eurekát használjuk, amely egy Netflix-fejlesztés
+ springes adoptációja. Az Eureka a beregisztrált szolgáltatásokat nem DB-ben tárolja, hanem memóriában, de a hibatűrés
+ érdekében az Eureka-szerver-példányok egymás közt replikálják az adataikat. Ezen kívül az Eureka-kliensek szintén
+ cache-elik a kereséseik eredményét, így jó hibatűrés jellemzi a megoldást. Mi most egyetlen Eureka-szervert fogunk
+ futtatni, így a konfigban azt állítottuk be, hogy ne próbáljon más Eureka-szerverekkel kommunikálni.
-5. Azt szeretnénk, hogy a többi induló alkalmazás (*flights, bonus, currency*, és a *config* is!) a discovery szerverünknél regisztrálja be magát induláskor. Ennek érdekében:
+5. Azt szeretnénk, hogy a többi induló alkalmazás (`flights`, `bonus`, `currency`, és a `config` is!) a discovery
+ szerverünknél regisztrálja be magát induláskor. Ennek érdekében:
- - Mindegyik pom.xml-jében helyezd el ezt a függőséget:
+ - Mindegyik `pom.xml`-jében helyezd el ezt a függőséget:
- ```
-
- org.springframework.cloud
- spring-cloud-starter-netflix-eureka-client
-
- ```
+ ```xml
+
+ org.springframework.cloud
+ spring-cloud-starter-netflix-eureka-client
+
+ ```
- - A config projektben lévő currency.yml, bonus.yml és flights.yml-be, valamint magát a config szervert konfigoló application.yml-be tedd bele ezeket a sorokat:
+ - A `config` projektben lévő `currency.yaml`, `bonus.yaml` és `flights.yaml`-be, valamint magát a config servert
+ konfigoló `application.yaml`-be tedd bele ezeket a sorokat:
- ```
- eureka:
- client:
- serviceUrl:
- defaultZone: http://localhost:8085/eureka/
- ```
+ ```yaml
+ eureka:
+ client:
+ serviceUrl:
+ defaultZone: http://localhost:8085/eureka/
+ ```
-6. Indítsd el sorban a config, discovery, flights, currency és bonus alkalmazásokat. Készíts egy screenshotot, amelyen egy böngészőben látszik megnyitva a http://localhost:8085/ URL. Ha más portot állítottál be a discovery szervernek, akkor értelemszerűen azt a portot nyisd meg. Az elvárt eredmény, hogy a regisztrált példányok közt látszodjon a config, a flights, a currency és a bonus alkalmazás is.
+6. Töltsd újra a Maven függőségeket.
+7. Indítsd el sorban a `ConfigApplication`-t, a `DiscoveryApplication`-t, a `FlightsApplication`-t, a
+ `CurrencyApplication`-t és a `BonusApplication`-t. Készíts egy screenshotot, amelyen egy böngészőben látszik
+ megnyitva a http://localhost:8085/ URL. Ha más portot állítottál be a discovery szervernek, akkor értelemszerűen azt
+ a portot nyisd meg. Az elvárt eredmény, hogy a regisztrált példányok közt látszodjon a CONFIG, a FLIGHTS, a CURRENCY
+ és a BONUS alkalmazás is.
## Következő feladat
diff --git a/spring-cloud/Feladat-3.md b/spring-cloud/Feladat-3.md
index c95b05b..a3744c3 100644
--- a/spring-cloud/Feladat-3.md
+++ b/spring-cloud/Feladat-3.md
@@ -1,25 +1,39 @@
-# 3. Feladat: API gateway
+# 3. feladat: API gateway
-A légitársaság nem akarja összes alkalmazását (sem pedig a discovery vagy a config servert) a belső hálózaton kívülről érkezők számára elérhetővé tenni, csak bizonyos jól definiált végpontokat. Ezért bevezetünk egy API gateway-t, amely kívülről elérhető lesz, és a kívülről érkező kéréseket a megfelelő microservice-hez továbbítja. Ehhez természetesen tudnia kell, hogy hol futnak ezek a szolgáltatások. Egy API gateway másik tipikus feladata az autorizáció kezelése, itt szoktak valamilyen kliens oldalról küldött token alapján user infokat (pl. JWT token formájában) beletenni a header-ök közé, vagy megfelelő kliens oldali token hiányában elutasítani a kérést. Így a gateway mögötti microservice-eknek már csak a user info kiolvasása a feladata. Jelenlegi példánkban az autorizációval nem foglalkozunk, kizárólag a kérések route-olására fókszálunk.
+A légitársaság nem akarja összes alkalmazását (sem pedig a discovery vagy a config servert) a belső hálózaton kívülről
+érkezők számára elérhetővé tenni, csak bizonyos jól definiált végpontokat. Ezért bevezetünk egy API gateway-t, amely
+kívülről elérhető lesz, és a kívülről érkező kéréseket a megfelelő microservice-hez továbbítja. Ehhez természetesen
+tudnia kell, hogy hol futnak ezek a szolgáltatások. Egy API gateway másik tipikus feladata az autorizáció kezelése, itt
+szoktak valamilyen kliensoldalról küldött token alapján user infókat (pl. JWT formájában) beletenni a headerök közé,
+vagy megfelelő kliensoldali token hiányában elutasítani a kérést. Így a gateway mögötti microservice-eknek már csak a
+user info kiolvasása a feladata. Jelenlegi példánkban az autorizációval nem foglalkozunk, kizárólag a kérések
+route-olására fókszálunk.
-1. Hozzuk létre a gateway szerver projektjét, Ismét célszerű a File > New > Spring Starter Project varázslót használni. A projekt neve legyen *gateway*. A következő oldalon a lehetséges függőségek közül válasszuk ki:
+1. Hozzuk létre a gatewayszerver projektjét! Ismét célszerű a _File_ > _New_ > _Spring Starter Project_ varázslót
+ használni. A projekt neve legyen `gateway`. A következő oldalon a lehetséges függőségek közül válasszuk ki:
- - A Spring Cloud Routing csoportból a Reactive Gateway-t, fontos, hogy nem a "sima" Gateway-t. (Így egy kész gateway implementációt kapunk, amit csak fel kell konfigolnunk.)
- - A Spring Cloud Config csoportból a Config Client-et. (Így az API gateway is a config szerverről fogja venni a saját konfigját.)
- - A Spring Cloud Discovery csoportból az Eureka Discovery Client-et. (Így az API gateway is be fog jelentkezni az eureka servernél, valamint az eureka servertől fogja megtudni a többi szolgáltatás aktuális címét.)
+ - A Spring Cloud Routing csoportból a ***Reactive*** *Gateway*t. (Így egy kész gateway implementációt kapunk, amit
+ csak fel kell konfigolnunk.)
+ - A Spring Cloud Config csoportból a *Config Client*et. (Így az API gateway is a config szerverről fogja venni a
+ saját konfigját.)
+ - A Spring Cloud Discovery csoportból az *Eureka Discovery Client*et. (Így az API gateway is be fog jelentkezni az
+ Eureka-szervernél, valamint az Eureka-szervertől fogja megtudni a többi szolgáltatás aktuális címét.)
-2. A konfig szerver használatához hozzuk létre az src\main\resources alá a application.properties fájlt, a szokásos tartalommal:
+2. A konfigszerver használatához hozzuk létre az `src\main\resources` alá az `application.properties` fájlt a szokásos
+ tartalommal:
```
spring.application.name=gateway
spring.config.import=optional:configserver:http://localhost:8081
```
-
-3. A main osztályra (GatewayApplication) tegyük rá az *@EnableDiscoveryClient* annotációt. Így fog tudni a gateway szolgáltatás címeket keresni a discovery szervernél.
-4. A config projektben az src\main\resources\config alá hozzuk létre a gateway.yml konfig fájlt, ilyen sorokkal:
+3. A main osztályra (`GatewayApplication`) tegyük rá az `@EnableDiscoveryClient` annotációt. Így fog tudni a
+ gatewayszolgáltatás címeket keresni a discovery servernél.
- ```
+4. A `config` projektben az `src\main\resources\config` alá hozzuk létre a `gateway.yaml` konfigfájlt az alábbi
+ sorokkal:
+
+ ```yaml
server:
port: 8080
eureka:
@@ -50,16 +64,33 @@ A légitársaság nem akarja összes alkalmazását (sem pedig a discovery vagy
- RewritePath=/flights(?/?.*), /api$\{segment}
```
- A port természetesen más legyen, ha a 8080-at már elhasználtad más célra, és az eureka portját is módosítsd, ha nálad nem 8085. A következő sorokban routing szabályok láthatók. Sorban, három különböző id alatt írjuk le, hogy milyen szabályok vonatkoznak a currency, bonus és flights alkalmazásokra. Csak a currency példáját írjuk le részletesen, a másik kettő ezzel teljesen analóg.
+ A port természetesen más legyen, ha a `8080`-at már elhasználtad más célra, és az Eureka portját is módosítsd, ha
+ nálad nem `8085`. A következő sorokban routingszabályok láthatók. Sorban, három különböző ID alatt írjuk le, hogy
+ milyen szabályok vonatkoznak a `currency`, `bonus` és `flights` alkalmazásokra. Csak a `currency` példáját írjuk le
+ részletesen, a másik kettő ezzel teljesen analóg.
- - Az uri: után azt írjuk le, hova kell továbbítani a kérést. Itt beégethetnénk egy konkrét URI-t, pl. http://localhost:8083 . Mi viszont nem ezt tesszük, hanem az *lb://currency* értékkel azt kérjük, hogy a gateway a discovery szervertől a currency alkalmazáshoz tartozó címek közül adjon vissza egyet. (Az lb a **l**oad **b**alancer rövidítése, hiszen több elérhető példány esetén így terheléselosztás valósul meg közöttük.)
- - A predicates alatt azt írjuk le, milyen feltételek esetén alkalmazódjon ez a szabály. Mi a - Path=/currency/** kifejezéssel azt érjük el, hogy ha a gatewayhez /currency-vel kezdődő uri-re érkezik a kérés, akkor az továbbítódjon a currency szolgáltatáshoz
- - Az eddigiek alapján, ahhoz, ha pl. a http://localhost:8080/currency/rate/USD/HUF címre érkezik egy kérés, az a http://localhost:8083/currency/rate/USD/HUF címre fog továbbítódni. Tudjuk viszont, hogy a tényleges cím ez lenne: http://localhost:8083/api/rate/USD/HUF . Ezt az eltérést több ponton is kezelhetjük, mi most azt a megoldást választjuk, hogy a routing szabálynál beállítunk egy path újraíró filtert is. A RewritePath filterünk két, vesszővel elválasztott reguláris kifejezéssel pont azt éri el, hogy a http://localhot:8080/currency/rate/USD/HUF kérés a http://localhost:8083/api/rate/USD/HUF címre érkezzen be. (Feltéve, hogy ezeket a portokat konfigoltuk be.)
+ - Az `uri:` után azt írjuk le, hova kell továbbítani a kérést. Itt beégethetnénk egy konkrét URI-t,
+ pl. http://localhost:8083 . Mi viszont nem ezt tesszük, hanem az `lb://currency` értékkel azt kérjük, hogy a
+ gateway a discovery servertől a `currency` alkalmazáshoz tartozó címek közül adjon vissza egyet. (Az `lb` a **l**
+ oad **b**alancer rövidítése, hiszen több elérhető példány esetén így terheléselosztás valósul meg közöttük.)
+ - A `predicates:` alatt azt írjuk le, milyen feltételek esetén alkalmazódjon ez a szabály. Mi a
+ `- Path=/currency/**` kifejezéssel azt érjük el, hogy ha a gatewayhez `/currency`-vel kezdődő URI-re érkezik a
+ kérés, akkor az továbbítódjon a `currency` szolgáltatáshoz
+ - Az eddigiek alapján ha pl. a http://localhost:8080/currency/rate/USD/HUF címre érkezik egy kérés, az
+ a http://localhost:8083/currency/rate/USD/HUF címre fog továbbítódni. Tudjuk viszont, hogy a tényleges cím ez
+ lenne: http://localhost:8083/api/rate/USD/HUF . Ezt az eltérést több ponton is kezelhetjük, mi most azt a
+ megoldást választjuk, hogy a routingszabálynál beállítunk egy pathújraíró filtert is. A `RewritePath` filterünk
+ két, vesszővel elválasztott reguláris kifejezéssel pont azt éri el, hogy
+ a http://localhost:8080/currency/rate/USD/HUF kérés a http://localhost:8083/api/rate/USD/HUF címre érkezzen be. (
+ Feltéve, hogy ezeket a portokat konfigoltuk be.)
-5. Indítsd el a légitársaság összes szerverét: config, discovery, gateway, flights, currency, bonus. Készíts két képernyőképet a jegyzőkönyvbe:
+5. Indítsd el a légitársaság szervereit: `ConfigApplication`, `DiscoveryApplication`, `GatewayApplication`,
+ `FlightsApplication`, `CurrencyApplication`, `BonusApplication`. Készíts két képernyőképet a jegyzőkönyvbe:
- 1. Az elsőn látszódjon a currency.yml megnyitva az IDE-ben, és mellette egy böngészőben az átváltó API meghívásának eredménye, USD -> HUF irány esetére, viszont **a gateway-en keresztül meghívva!**
- 2. A másodikon látszódjon a bonus.yml megnyitva az IDE-ben, és mellette egy böngészőben a saját NEPTUN kódodnak megfelelelő user bonusának lekérdezése, **a gateway-en keresztül meghívva!**
+ 1. Az elsőn látszódjon a `currency.yaml` megnyitva az IDE-ben, és mellette egy böngészőben az átváltó API
+ meghívásának eredménye USD -> HUF irány esetére, viszont **a gatewayen keresztül meghívva!**
+ 2. A másodikon látszódjon a `bonus.yaml` megnyitva az IDE-ben, és mellette egy böngészőben a saját Neptun-kódodnak
+ megfelelelő user bonusának lekérdezése **a gatewayen keresztül meghívva!**
## Következő feladat
diff --git a/spring-cloud/Feladat-4.md b/spring-cloud/Feladat-4.md
index dc2b099..7dfd850 100644
--- a/spring-cloud/Feladat-4.md
+++ b/spring-cloud/Feladat-4.md
@@ -1,70 +1,93 @@
# 4. Feladat: OpenFeign
-Most, hogy a légitársaság microservice architektúrája készen áll, valósítsuk meg az utazási iroda booking alkalamzásában szereplő repjegy vásárló végpontot. Ezt a BookingController.buyTicket metódusban kell megvalósítani, az alábbi szabályok szerint (minden végpontot az API gateway-en keresztül kell meghívni):
-
-1. A TicketData-ban szereplő from és to mező alapján végezz egy keresést a flights API meghívásával. Ha nincs találat, egyből visszaadandó egy olyan PurchaseData, amiben a success értéke false.
-2. Ha van találat, akkor a legolcsóbbal dolgozz tovább. Tegyük fel, hogy a vásárlást USD-ben fogják kifizetni, ezért minden találat árát váltsd át USD-re a currency API meghívásával, hacsak nem eleve USD-ben kaptad meg a fligts API-tól.
-3. Ha a TicketData-ban a useBonus true-ra van állítva, kérdezzük le a user (szintén ott van a TicketData-ban) jelenlegi bónusz pontjait a bonus API meghívásával. Ha van bónusz pontja, azokat felhasználjuk a vásárlásnál 1 USD = 1 bónusz pont értékben vagyis:
- - Számítsuk ki mennyi bónuszpontot használhatunk fel (a fizetendő végső ár nem lehet negatív, akármennyi bónuszunk is van). Ezt az bónusz pontszámot vonjuk is le a bonus API-n keresztül a usertől, majd ezt állítsuk be a válasz purchaseDate bonusUsed mezőjébe.
- - A felhasznált bónuszpontokkal csökkentett árat állítsuk be a válasz purhcaseData price mezőjébe.
-4. A ténylegesen fizetendő árnak megfelelő bonus pontszámot (az ár szorozva konfigból beolvasott bonusRate értékkel) írjuk jóva a usernek a bonus API-n keresztül, majd ezt az értéket állítsuk be a válasz purchaseDate bonusEarned mezőjébe.
-5. Ha a fenti lépések hiba nélkül végigfutottak, legyen a válasz purchaseData success mezője true, ellenkező esetben false.
-
-A fenti logika lekódolása önálló feladat, előtte viszont közösen oldjuk meg azt a problémáat, hogy a BookingController-ből meg tudjuk hívni a gateway-en keresztül elérhető API-kat, a bonus példáján keresztül, értelemszerűen ezeket a lépéseket kell majd elvégezni a másik két projektnél is. Több módon meg lehet hívni Java-ból REST API-t:
+Most, hogy a légitársaság microservice architektúrája készen áll, valósítsuk meg az utazási iroda booking alkalamzásában
+szereplő repjegy vásárló végpontot. Ezt a BookingController.buyTicket metódusban kell megvalósítani, az alábbi szabályok
+szerint (minden végpontot az API gateway-en keresztül kell meghívni):
+
+1. A TicketData-ban szereplő from és to mező alapján végezz egy keresést a flights API meghívásával. Ha nincs találat,
+ egyből visszaadandó egy olyan PurchaseData, amiben a success értéke false.
+2. Ha van találat, akkor a legolcsóbbal dolgozz tovább. Tegyük fel, hogy a vásárlást USD-ben fogják kifizetni, ezért
+ minden találat árát váltsd át USD-re a currency API meghívásával, hacsak nem eleve USD-ben kaptad meg a fligts
+ API-tól.
+3. Ha a TicketData-ban a useBonus true-ra van állítva, kérdezzük le a user (szintén ott van a TicketData-ban) jelenlegi
+ bónusz pontjait a bonus API meghívásával. Ha van bónusz pontja, azokat felhasználjuk a vásárlásnál 1 USD = 1 bónusz
+ pont értékben vagyis:
+ - Számítsuk ki mennyi bónuszpontot használhatunk fel (a fizetendő végső ár nem lehet negatív, akármennyi bónuszunk
+ is van). Ezt az bónusz pontszámot vonjuk is le a bonus API-n keresztül a usertől, majd ezt állítsuk be a válasz
+ purchaseDate bonusUsed mezőjébe.
+ - A felhasznált bónuszpontokkal csökkentett árat állítsuk be a válasz purhcaseData price mezőjébe.
+4. A ténylegesen fizetendő árnak megfelelő bonus pontszámot (az ár szorozva konfigból beolvasott bonusRate értékkel)
+ írjuk jóva a usernek a bonus API-n keresztül, majd ezt az értéket állítsuk be a válasz purchaseDate bonusEarned
+ mezőjébe.
+5. Ha a fenti lépések hiba nélkül végigfutottak, legyen a válasz purchaseData success mezője true, ellenkező esetben
+ false.
+
+A fenti logika lekódolása önálló feladat, előtte viszont közösen oldjuk meg azt a problémáat, hogy a
+BookingController-ből meg tudjuk hívni a gateway-en keresztül elérhető API-kat, a bonus példáján keresztül,
+értelemszerűen ezeket a lépéseket kell majd elvégezni a másik két projektnél is. Több módon meg lehet hívni Java-ból
+REST API-t:
- A java.net.URLConnection osztályon keresztül (nagyon alacsony szintű megoldás)
- A Spring RestTemplate-jén keresztül: https://www.baeldung.com/rest-template
-- A szintén Spring által nyújtott, kicsit szebb API-t biztosító WebClient-en keresztül: https://www.baeldung.com/spring-5-webclient
+- A szintén Spring által nyújtott, kicsit szebb API-t biztosító WebClient-en
+ keresztül: https://www.baeldung.com/spring-5-webclient
-- Mi azt fogjuk kihasználni, hogy az API-nk definíciója már rendelkezésre áll Spring MVC annotációkkal elllátott interfész formájában. (Az *-api projektekben.) Ilyen esetben a [Spring Cloud OpenFeign](https://docs.spring.io/spring-cloud-openfeign/docs/2.2.5.RELEASE/reference/html/) futási időben tudja generálni az API-t meghívó klienst, vagyis az API kliens oldali meghívása úgy fog megjelenni, mint egy egyszerű metódushívás ezen az interfészen. Az alábbi lépések szükségesek ehhez:
+- Mi azt fogjuk kihasználni, hogy az API-nk definíciója már rendelkezésre áll Spring MVC annotációkkal elllátott
+ interfész formájában. (Az *-api projektekben.) Ilyen esetben
+ a [Spring Cloud OpenFeign](https://docs.spring.io/spring-cloud-openfeign/docs/2.2.5.RELEASE/reference/html/) futási
+ időben tudja generálni az API-t meghívó klienst, vagyis az API kliens oldali meghívása úgy fog megjelenni, mint egy
+ egyszerű metódushívás ezen az interfészen. Az alábbi lépések szükségesek ehhez:
- - A spring-cloud-starter-openfeign függőség már készen áll a bonus-api pom.xml-jében
+ - A spring-cloud-starter-openfeign függőség már készen áll a bonus-api pom.xml-jében
- - Helyezd el az alábbi annotációt a BonusApi interfészen, amivel azt fejezzük ki, hogy a bonus nevű Feign API kliens majd a feign.bonus.url uri-n keresztül lesz elérhető
+ - Helyezd el az alábbi annotációt a BonusApi interfészen, amivel azt fejezzük ki, hogy a bonus nevű Feign API kliens
+ majd a feign.bonus.url uri-n keresztül lesz elérhető
- ```
- @FeignClient(name = "bonus", url = "${feign.bonus.url}")
- ```
+ ```
+ @FeignClient(name = "bonus", url = "${feign.bonus.url}")
+ ```
- - A booking pom.xml-jébe helyezd el függőségként a bonus-api-t (ez tranzitív módon magával hozza az openfeign startert is):
+ - A booking pom.xml-jébe helyezd el függőségként a bonus-api-t (ez tranzitív módon magával hozza az openfeign
+ startert is):
- ```
-
- hu.bme.aut.szoftlab
- bonus-api
- 0.0.1-SNAPSHOT
-
- ```
+ ```
+
+ hu.bme.aut.szoftlab
+ bonus-api
+ 0.0.1-SNAPSHOT
+
+ ```
- - A BookingApplication osztályon helyezd el ezt az annotációt:
+ - A BookingApplication osztályon helyezd el ezt az annotációt:
- ```
- @EnableFeignClients(basePackageClasses = {BonusApi.class})
- ```
+ ```
+ @EnableFeignClients(basePackageClasses = {BonusApi.class})
+ ```
- - A booking projekt src\main\resources\application.properties fájlba tedd be ezt a sort:
+ - A booking projekt src\main\resources\application.properties fájlba tedd be ezt a sort:
- ```
- feign.bonus.url=http://localhost:8080/bonus
- ```
+ ```
+ feign.bonus.url=http://localhost:8080/bonus
+ ```
- - A Feign által generált API kliens injektálható pl. a BookingControllerbe:
+ - A Feign által generált API kliens injektálható pl. a BookingControllerbe:
- ```
- @Autowired
- BonusApi bonusApi;
- ```
+ ```
+ @Autowired
+ BonusApi bonusApi;
+ ```
-Miután a másik két API klienst is bekötötted, és segítségükkel megvalósítottad a fent definiált üzleti logikát, indítsd el az összes alkalmazást: config, discovery, gateway, flights, bonus, currency, booking. Postman-en keresztül végezz el három hívást, amelyekről készíts screenshotot:
+Miután a másik két API klienst is bekötötted, és segítségükkel megvalósítottad a fent definiált üzleti logikát, indítsd
+el az összes alkalmazást: config, discovery, gateway, flights, bonus, currency, booking. Postman-en keresztül végezz el
+három hívást, amelyekről készíts screenshotot:
-1. Jegyvásárlás Budapestről Prágába, user a saját neptun kódod, bónusz felhasználásával (frissen indítsd a bonus alkalmazást, hogy 0 bónusza legyen a userednek.)
+1. Jegyvásárlás Budapestről Prágába, user a saját neptun kódod, bónusz felhasználásával (frissen indítsd a bonus
+ alkalmazást, hogy 0 bónusza legyen a userednek.)
2. Jegyvásárlás Budapestről Prágába, user a saját neptun kódod, bónusz felhasználása nélkül
3. Jegyvásárlás Budapestről Prágába, user a saját neptun kódod, bónusz felhasználásával
-
-
## Végeztél
Végeztél a feladatokkal.
diff --git a/spring-cloud/README.md b/spring-cloud/README.md
index fd8bb79..27d7760 100644
--- a/spring-cloud/README.md
+++ b/spring-cloud/README.md
@@ -1,8 +1,13 @@
# Microservice architektúra Spring Cloud platformon
-A labor során 3 önálló Spring Boot-os alkalmazásból indulunk ki (*bonus, flights, currency*), amelyeket fokozatosan egészítünk ki egy Microservice architektúrához szükséges elemekkel (config server, service registre, API gateway). Az architektúra tesztelésére egy negyedik alkalmazás fog szolgálni (*booking*), amely az API gateway-en keresztül hív majd meg több REST API-t egy összetett üzleti logika elvégzéséhez.
+A labor során 3 önálló Spring Boot-os alkalmazásból indulunk ki (*bonus, flights, currency*), amelyeket fokozatosan
+egészítünk ki egy Microservice architektúrához szükséges elemekkel (config server, service registre, API gateway). Az
+architektúra tesztelésére egy negyedik alkalmazás fog szolgálni (*booking*), amely az API gateway-en keresztül hív majd
+meg több REST API-t egy összetett üzleti logika elvégzéséhez.
-A fő cél, hogy a Spring Cloud által adott lehetőségeket egy példán keresztül illusztráljuk, így a labor legnagyobb részében a leírásban szereplő konfigurációkat kell bemásolni, csak a legvégén szerepel egy kisebb önállóan megoldandó feladat.
+A fő cél, hogy a Spring Cloud által adott lehetőségeket egy példán keresztül illusztráljuk, így a labor legnagyobb
+részében a leírásban szereplő konfigurációkat kell bemásolni, csak a legvégén szerepel egy kisebb önállóan megoldandó
+feladat.
## Előfeltételek, felkészülés
@@ -10,15 +15,17 @@ A labor elvégzéséhez szükséges eszközök:
- JDK 17, pl. innen: https://adoptium.net/?variant=openjdk17
- Tetszőleges Java alapú IDE, pl. Spring Tools 4 for Eclipse: https://spring.io/tools
-- HTTP kérések egyszerű összeállítását lehetővé tevő fejlesztői eszköz, pl.: [Postman](https://www.postman.com/downloads/)
+- HTTP-kérések egyszerű összeállítását lehetővé tevő fejlesztői eszköz,
+ pl.: [Postman](https://www.postman.com/downloads/)
A laborok elvégzéséhez használható segédanyagok és felkészülési anyagok:
+
- A Háttéralkalmazások tárgy kapcsolódó előadásai:
- - https://www.aut.bme.hu/Upload/Course/VIAUBB04/hallgatoi_jegyzetek/12-Microservices.pdf
- - https://web.microsoftstream.com/video/6e6642e0-bce5-48e5-bfcd-27d27cc22875?channelId=2c22f965-126a-4fe8-bbbd-71e5cd85a7c4
- - https://web.microsoftstream.com/video/1453a714-dcd7-4946-b53d-19fe60f67f4c?channelId=2c22f965-126a-4fe8-bbbd-71e5cd85a7c4
+ - https://www.aut.bme.hu/Upload/Course/VIAUBB04/hallgatoi_jegyzetek/12-Microservices.pdf
+ - https://web.microsoftstream.com/video/6e6642e0-bce5-48e5-bfcd-27d27cc22875?channelId=2c22f965-126a-4fe8-bbbd-71e5cd85a7c4
+ - https://web.microsoftstream.com/video/1453a714-dcd7-4946-b53d-19fe60f67f4c?channelId=2c22f965-126a-4fe8-bbbd-71e5cd85a7c4
Hivatalos dokumentációk:
@@ -29,65 +36,92 @@ Hivatalos dokumentációk:
## Beadandó
-A labor elvégzése után az alábbi tartalmat kérjük beadni a tanszéki portálra történő feltöltéssel, egy zipelt fájlban:
-- **PDF** formátumban (DOCX nem elfogadott!) az egyes feladatoknál pontosan megnevezett:
- - konkrét kódrészletekről készített képernyőkép(ek),
- - 1 mondatos magyarázat
- - 1 vagy több ábra (jellemzően képernyőkép), ami a helyes működést hivatott bizonyítani.
-- A booking projekt forrása (src\main mappa elegendő)
+A labor elvégzése után az alábbi tartalmat kérjük beadni a Moodle-re történő feltöltéssel, egy zipelt fájlban:
+
+- **PDF** formátumban (`.docx` nem elfogadott!) az egyes feladatoknál pontosan megnevezett:
+ - konkrét kódrészletekről készített képernyőkép(ek),
+ - 1 mondatos magyarázat
+ - 1 vagy több ábra (jellemzően képernyőkép), ami a helyes működést hivatott bizonyítani.
+- A `booking` projekt forrása (az `src\main` mappa elegendő)
## Értékelés
-A laborban négy feladatrész van. Jeles osztályzat az összes feladatrész elvégzésével kapható. Minden hiányzó, avagy hiányos feladatrész mínusz egy jegy.
+A laborban négy feladatrész van. Jeles osztályzat az összes feladatrész elvégzésével kapható. Minden hiányzó, avagy
+hiányos feladatrész mínusz egy jegy.
## A meglévő kód áttekintése
-Klónozd ezt a repository-t, és a spring-cloud mappában lévő 7 projektet importáld az IDE-be maven projektként! A bonus, currency és flights alkalmazásokban külön projektbe van kiszervezve a REST API-t definiáló interfész, ami majd hasznos lesz nekünk később. Ezek a bonus-api, currency-api és flights-api projektek. Ez a három önálló alkalmazás egy-egy jól definiált funkcióért felel, ezért a légitársaság, amelynek az üzletmenetét támogatják, 3 külön microservice formájában fejlesztette őket. Vegyük sorra a projekteket:
+Klónozd ezt a repositoryt, és a `spring-cloud` mappában lévő 7 projektet importáld az IDE-be Maven projektként! A
+`bonus`, `currency` és `flights` alkalmazásokban külön projektbe van kiszervezve a REST API-t definiáló interfész, ami
+majd hasznos lesz nekünk később. Ezek a `bonus-api`, `currency-api` és `flights-api` projektek. Ez a három önálló
+alkalmazás egy-egy jól definiált funkcióért felel, ezért a légitársaság, amelynek az üzletmenetét támogatják, 3 külön
+microservice formájában fejlesztette őket. Vegyük sorra a projekteket:
+
+- `bonus-api`:
+
+ - A `BonusApi` interfész Spring MVC annotációkkal definiál két végpontot: egy adott user eddig összegyűjtött
+ bónuszpontjait tudjuk lekérdezni (GET), vagy egy adott usernek tudunk új pontokat adni (PUT)
+
+- `bonus`:
+
+ - A `BonusController` valósítja meg a `BonusApi` interfészt. A felhasználók bónuszpontjait az alkalmazás relációs
+ adatbázisban tárolja. (Az egyszerűség kedvéért ez egy beágyazott H2 adatbázis, ahogy a POM-függőségek között
+ látható.) Az egyetlen táblát a `Bonus` JPA-entitásra képezzük le, amelyet a `BonusRepository` interfészen
+ keresztül manipulálunk. A bónuszlekérdező végpont megvalósításában látszik, hogy nem létező felhasználó
+ lekérdezése esetén 0 pontot adunk vissza. Bónuszpont hozzáadásakor viszont a `BonusService`-be kiszervezett üzleti
+ logika létrehoz egy új bejegyzést a felhasználóhoz 0 ponttal, ha az még nem létezett, így mindenképp egy létező
+ pontszámot módosítunk. A pontszám negatív is lehet, ezzel kezeljük a pontszám felhasználását vásárlási célból.
+ 400-as `Bad Request` választ adunk, ha a meglévő pontszámnál nagyobbat akarnak levonni.
-- bonus-api:
+- `currency-api`:
- - A BonusApi interfész Spring MVC annotációkkal definiál két végpontot: egy adott user eddig összegyűjtött bónuszpontjait tudjuk lekérdezni (GET), vagy egy adott usernek tudunk új pontokat adni (PUT)
+ - A `CurrencyApi` interfész Spring MVC-annotációkkal definiál egy végpontot: egyik valutáról a másikra adja meg az
+ átváltási árfolyamot
-- bonus:
+- `currency`:
- - A BonusController valósítja meg a BonusApi interfészt. A felhasználók bónuszpontjait az alkalmazás relációs adatbázisban tárolja. (Az egyszerűség kedvéért ez egy beágyazott H2 adatbázis, ahogy a pom függőségek között látható.) Az egyetlen táblát a *Bonus* JPA entitásra képezzük le, amelyet a BonusRepository interfészen keresztül manipulálunk. A bónusz lekérdező végpont megvalósításában látszik, hogy nem létező felhasználó lekérdezése esetén 0 pontot adunk vissza. Bónuszpont hozzáadásakor viszont a BonusService-be kiszervezett üzleti logika létrehoz egy új bejegyzést, 0 ponttal a felhasználóhoz, ha az még nem létezett, így mindenképp egy létező pontszámot módosítunk. A pontszám negatív is lehet, ezzel kezeljük a pontszám felhasználását vásárlási célból. 400-as Bad Request választ adunk, ha a meglévő pontszámnál nagyobbat akarnak levonni.
+ - A `CurrencyController` valósítja meg a `CurrencyApi` interfészt a `CurrencyService` felhasználásával. A
+ `CurrencyService` az egyszerűség kedvéért csak a memóriába beégetve tartalmaz 6 árfolyamot. Ami fontos lesz, hogy
+ ugyanazon valuta oda- és visszairányú váltása nem egyenértékű, egy konfigurálható átváltási jutalékkal dolgozik az
+ alkalmazás. Az átváltási jutalék mértékét a konfigból ilyen módon nyerjük ki a `CurrencyService`-ben:
-- currency-api:
+ ```java
+ @Value("${currency.exchangePremium}")
+ private double exchangePremium;
+ ```
- - A CurrencyApi interfész Spring MVC annotációkkal definiál egy végpontot: egyik valutáról a másikra adja meg az átváltási árfolyamot
+ Majd így használjuk fel:
-- currency:
+ ```java
+ new RateDescriptor("HUF", "EUR"), 1.0 / 370,
+ new RateDescriptor("EUR", "HUF"), 370.0*(1 + exchangePremium),
+ ```
+ Az `src\main\resources\application.yml` fájlban látható, hogy jelenleg 1%-os az átváltási jutalék:
- - A CurrencyController valósítja meg a CurrencyApi interfészt, a CurrencyService felhasználásával. A CurrencyService az egyszerűség kedvéért csak memóriában beégetve tartalmaz 6 árfolyamot. Ami fontos lesz, hogy ugyanazon valuta oda- és visszairányú váltása nem egyenértékű, van egy konfigurálható átváltási jutalékkal dolgozik az alkalmazás. Az átváltási jutalék mértékét a konfigból ilyen módon nyerjük ki a CurrencyService-ben:
+ ```yaml
+ currency:
+ exchangePremium: 0.01
+ ```
- ```
- @Value("${currency.exchangePremium}")
- private double exchangePremium;
- ```
+- `flights-api`:
- Majd így használjuk fel:
+ - A `FlightsApi` interfész Spring MVC-annotációkkal definiál egy végpontot, amelyen járatokat lehet keresni a
+ felszállási és leszállási város megadásával. A válaszban `Airline` listát ad a végpont, egy `Airline`-nak ID-je,
+ kiinduló- és célvárosa, ára és pénzneme van. Az `Airline` osztály értelmeszerűen szintén ebben a projektben van
+ definiálva.
- ```
- new RateDescriptor("HUF", "EUR"), 1.0 / 370,
- new RateDescriptor("EUR", "HUF"), 370.0*(1 + exchangePremium),
- ```
- Az src\main\resources\application.yml fájlban látható, hogy jelenleg 1%-os az átváltási jutalék:
+- `flights`:
- ```
- currency:
- exchangePremium: 0.01
- ```
-
+ - A `FlightsController` valósítja meg a `FlightsApi`-t az `AirlineService` segítségével. Ez az egyszerűség kedvéért
+ lineáris keresést végez egy memóriába beégetett `Airline` listában.
-- flights-api:
-
- - A FlightsApi interfész Spring MVC annotációkkal definiál egy végpontot, amelyen járatokat lehet keresni a felszálló és leszálló város megadásával. A válaszban Airline listát ad a végpont, egy Airline-nak id-je, kiinduló- és célvárosa, ára és pénzneme van. Az Airline osztály értelmeszerűen szintén az api projektben van definiálva.
-- flights:
-
- - A FlightsController valósítja meg a FlightsApi-t, az AirlineService segítségével. Ez az egyszerűség kedvéért lineáris keresést végez egy memóriába beégetett Airline listában.
+- `booking`:
-A hetedik projekt neve *booking*. Ez nem a légitársaság, hanem egy utazási iroda rendszere, amely a légitársaság fenti szolgáltatásait felhasználva biztosít repjegy vásárló funkcionalitást. A BookingController-ben látható, hogy egy TicketData-t fogad el POST törzsként, majd erre egy PurchaseData választ ad. A pontos elvárt működést majd a 4. feladat specifikálja, de a megvalósítás során mindhárom légitársasági rendszert meg kell majd hívni.
+ - Ez nem a légitársaság, hanem egy utazási iroda rendszere, amely a légitársaság fenti szolgáltatásait felhasználva
+ biztosít repjegyvásárló funkcionalitást. A `BookingController`-ben látható, hogy egy `TicketData`-t fogad el POST
+ törzsként, majd erre egy `PurchaseData` választ ad. Az elvárt működést majd a 4. feladat fogja specifikálni, a
+ megvalósítás során mindhárom légitársasági rendszert meg kell majd hívni.
## Feladatok
-Összesen 4 feladat van. [Itt kezdd](Feladat-1.md) az első feladattal.
\ No newline at end of file
+Összesen 4 feladat van. [Itt kezdd](Feladat-1.md) az elsővel.
\ No newline at end of file