From 4a43138c497ecd9100b58e59e319f5b88a145a91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Gy=C3=B6ngy=C3=B6si?= Date: Mon, 14 Oct 2024 09:23:25 +0200 Subject: [PATCH 1/4] Changed `.yml` to `.yaml`; corrected grammar; improved formatting --- spring-cloud/Feladat-1.md | 111 +++++++++++++++++++------------------- spring-cloud/Feladat-2.md | 29 +++++----- spring-cloud/Feladat-3.md | 34 ++++++------ spring-cloud/README.md | 58 ++++++++++---------- 4 files changed, 119 insertions(+), 113 deletions(-) diff --git a/spring-cloud/Feladat-1.md b/spring-cloud/Feladat-1.md index e907237..58d09da 100644 --- a/spring-cloud/Feladat-1.md +++ b/spring-cloud/Feladat-1.md @@ -1,31 +1,32 @@ -# 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 +36,10 @@ 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,32 +54,36 @@ 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 ``` + + - A `currency.yaml`-ben pedig ezen felül még az átváltási jutalékot is állítsuk 1,5%-ra: -5. A config projekt main osztályára (ConfigApplication) tegyük rá a *@EnableConfigServer* annotációt, ezzel a konfig szerver elkészült. + ```yaml + currency: + exchangePremium: 0.015 + ``` -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. +5. A `config` projekt main osztályára (`ConfigApplication`) tegyük rá a `@EnableConfigServer` annotációt, ezzel a konfigszerver elkészült. - - A pom.xml-ben: +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 <properties> tagbe helyezzük el ezt a sort: + - A `pom.xml`-ben: - ``` + - A `` tagbe helyezzük el ezt a sort: + + ```xml 2023.0.3 ``` - - A <properties> tag alá helyezzük el ezeket a sorokat: + - A `` tag alá helyezzük el ezeket a sorokat: - ``` + ```xml @@ -93,45 +97,44 @@ De a légitársaság a belső szolgáltatásait nem az egyes alkalmazások bels ``` - - A spring-boot-starter-web függőség után illesszük be ezeket a sorokat: + - 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 ``` - - 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): + - 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 ``` - - 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. + - 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 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.) +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.) ![Boot Dashboard](images/boot-dashboard.png) 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 diff --git a/spring-cloud/Feladat-2.md b/spring-cloud/Feladat-2.md index cd4c83c..c1e8a2d 100644 --- a/spring-cloud/Feladat-2.md +++ b/spring-cloud/Feladat-2.md @@ -1,21 +1,21 @@ -# 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. +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: +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 +28,30 @@ 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: - ``` + ```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: - ``` + ```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 1c05b97..f15045a 100644 --- a/spring-cloud/Feladat-3.md +++ b/spring-cloud/Feladat-3.md @@ -1,25 +1,25 @@ -# 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 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 *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. +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.yml konfig fájlt, ilyen sorokkal: +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 +50,16 @@ 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/README.md b/spring-cloud/README.md index fd8bb79..8e8c6cf 100644 --- a/spring-cloud/README.md +++ b/spring-cloud/README.md @@ -2,7 +2,7 @@ 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,7 +10,7 @@ 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/)
@@ -30,11 +30,11 @@ 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), +- **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 `booking` projekt forrása (az `src\main` mappa elegendő) ## Értékelés @@ -42,52 +42,54 @@ A laborban négy feladatrész van. Jeles osztályzat az összes feladatrész elv ## 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: +- `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) + - 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: +- `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ó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 `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. -- currency-api: +- `currency-api`: - - 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 + - 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 -- currency: +- `currency`: - - 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: + - 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: - ``` + ```java @Value("${currency.exchangePremium}") private double exchangePremium; ``` - Majd így használjuk fel: + Majd így használjuk fel: - ``` + ```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: + Az `src\main\resources\application.yml` fájlban látható, hogy jelenleg 1%-os az átváltási jutalék: - ``` + ```yaml currency: exchangePremium: 0.01 ``` - -- 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. +- `flights-api`: + + - 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. + +- `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 From 0cf55decada74c83fb34a32f3e1df584655b50c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Gy=C3=B6ngy=C3=B6si?= Date: Mon, 14 Oct 2024 09:50:30 +0200 Subject: [PATCH 2/4] Updated submission location from department portal to Moodle --- spring-cloud/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-cloud/README.md b/spring-cloud/README.md index 8e8c6cf..78d2976 100644 --- a/spring-cloud/README.md +++ b/spring-cloud/README.md @@ -29,7 +29,7 @@ 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: +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 From b20bb9752d047f74a8652077021d5be356733107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Gy=C3=B6ngy=C3=B6si?= Date: Mon, 18 Nov 2024 01:36:35 +0100 Subject: [PATCH 3/4] Run auto reformatting --- spring-cloud/Feladat-1.md | 185 +++++++++++++++++++++++--------------- spring-cloud/Feladat-2.md | 64 ++++++++----- spring-cloud/Feladat-3.md | 63 +++++++++---- spring-cloud/Feladat-4.md | 109 +++++++++++++--------- spring-cloud/README.md | 96 +++++++++++++------- 5 files changed, 330 insertions(+), 187 deletions(-) diff --git a/spring-cloud/Feladat-1.md b/spring-cloud/Feladat-1.md index 58d09da..443a4bd 100644 --- a/spring-cloud/Feladat-1.md +++ b/spring-cloud/Feladat-1.md @@ -1,14 +1,25 @@ # 1. feladat: Config server -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. +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ő 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: +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 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. +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(-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): +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 @@ -23,8 +34,10 @@ De a légitársaság a belső szolgáltatásait nem az egyes alkalmazások bels ``` - - 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 @@ -37,7 +50,8 @@ 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 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: +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: @@ -54,14 +68,18 @@ 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 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. + 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: +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 ``` - + - A `currency.yaml`-ben pedig ezen felül még az átváltási jutalékot is állítsuk 1,5%-ra: ```yaml @@ -69,74 +87,93 @@ De a légitársaság a belső szolgáltatásait nem az egyes alkalmazások bels 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.) +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.) ![Boot Dashboard](images/boot-dashboard.png) 8. Készíts két képernyőképet a jegyzőkönyvbe: - 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 - - + 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 c1e8a2d..3e1f14e 100644 --- a/spring-cloud/Feladat-2.md +++ b/spring-cloud/Feladat-2.md @@ -1,19 +1,28 @@ # 2. feladat: Discovery server -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. +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 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.) +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.yaml` néven az alábbi tartalommal: +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: @@ -28,30 +37,41 @@ Egy microservice architektúrában célszerű egy discovery serveren nyilvántar 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 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. + 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: - ```xml - - 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.yaml`, `bonus.yaml` és `flights.yaml`-be, valamint magát a config servert konfigoló `application.yaml`-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: - ```yaml - eureka: - client: - serviceUrl: - defaultZone: http://localhost:8085/eureka/ - ``` + ```yaml + eureka: + client: + serviceUrl: + defaultZone: http://localhost:8085/eureka/ + ``` 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. +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 0c4d9cd..a3744c3 100644 --- a/spring-cloud/Feladat-3.md +++ b/spring-cloud/Feladat-3.md @@ -1,23 +1,37 @@ # 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 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. +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 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: +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. (Í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.) + - 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 konfigszerver használatához hozzuk létre az `src\main\resources` alá az `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 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: +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: @@ -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 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. + 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 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.) + - 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 szervereit: `ConfigApplication`, `DiscoveryApplication`, `GatewayApplication`, `FlightsApplication`, `CurrencyApplication`, `BonusApplication`. 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.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!** + 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 78d2976..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: @@ -30,65 +37,90 @@ Hivatalos dokumentációk: ## Beadandó 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. + - 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 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: +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) + - 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. + - 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. - `currency-api`: - - 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 + - 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 - `currency`: - - 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: + - 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: - ```java - @Value("${currency.exchangePremium}") - private double exchangePremium; - ``` + ```java + @Value("${currency.exchangePremium}") + private double exchangePremium; + ``` - Majd így használjuk fel: + Majd így használjuk fel: - ```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: + ```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: - ```yaml - currency: - exchangePremium: 0.01 - ``` + ```yaml + currency: + exchangePremium: 0.01 + ``` - `flights-api`: - - 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. + - 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. - `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. + - 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`: - - 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. + - 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 From dfe820774422f03917bdcea5892d63a40cd37aff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Gy=C3=B6ngy=C3=B6si?= Date: Mon, 18 Nov 2024 01:36:48 +0100 Subject: [PATCH 4/4] Improve grammar --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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)