From f43f09a29c6414c7914efd5a62331e5ad0b6bd7c Mon Sep 17 00:00:00 2001 From: Sizolwakhe Leonard Mthimunye Date: Thu, 11 Sep 2025 00:23:32 +0200 Subject: [PATCH 1/7] enabling spring boot caching --- src/main/java/org/airpenthouse/GoTel/GoTelApplication.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/airpenthouse/GoTel/GoTelApplication.java b/src/main/java/org/airpenthouse/GoTel/GoTelApplication.java index 4c02a6a..4ef826b 100644 --- a/src/main/java/org/airpenthouse/GoTel/GoTelApplication.java +++ b/src/main/java/org/airpenthouse/GoTel/GoTelApplication.java @@ -4,12 +4,10 @@ import org.airpenthouse.GoTel.util.PropertiesUtilManager; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; +import org.springframework.cache.annotation.EnableCaching; -@Configuration -@PropertySource("classpath:application.properties") @SpringBootApplication +@EnableCaching public class GoTelApplication { public static void main(String[] args) { From 70bf40227c0616fdca29c43037d67de3ad595773 Mon Sep 17 00:00:00 2001 From: Sizolwakhe Leonard Mthimunye Date: Thu, 11 Sep 2025 00:26:34 +0200 Subject: [PATCH 2/7] Adding dependencies for caching and creating sessions with spring boot,redis and docker --- pom.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pom.xml b/pom.xml index 9a7281c..ea26fea 100644 --- a/pom.xml +++ b/pom.xml @@ -56,6 +56,18 @@ mysql-connector-java 8.0.33 + + org.springframework.boot + spring-boot-starter-data-redis + + + org.springframework.boot + spring-boot-docker-compose + + + org.springframework.session + spring-session-data-redis + org.projectlombok lombok From 72f99097905f281b62c72a18c3e554c672de54f2 Mon Sep 17 00:00:00 2001 From: Sizolwakhe Leonard Mthimunye Date: Thu, 11 Sep 2025 00:27:28 +0200 Subject: [PATCH 3/7] yml file that contains redis properties --- docker-compose.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 docker-compose.yml diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..34d61dd --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,15 @@ +version: '3.8' + +services: + redis: + image: redis:latest + container_name: redis_container + ports: + - "6379:6379" # Expose Redis on port 6379 + volumes: + - redis_data:/data # Persist data + command: ["redis-server", "--appendonly", "yes"] # Enable AOF persistence + +volumes: + redis_data: + driver: local \ No newline at end of file From bc6e5cd71f55df7002b47446e453c79dc518d714 Mon Sep 17 00:00:00 2001 From: Sizolwakhe Leonard Mthimunye Date: Thu, 11 Sep 2025 00:28:44 +0200 Subject: [PATCH 4/7] add property for start docker once --- src/main/resources/application.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index cb50cb8..3a7fca0 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,6 +1,7 @@ spring.application.name=GoTel jdbc.url=jdbc:mysql://localhost:3306/world jdbc.username=root +spring.docker.compose.lifecycle-management=start_only #Retrieve all jdbc.query.allCountries=SELECT * FROM `country` jdbc.query.allLanguage=SELECT country.Name,countrylanguage.Language,countrylanguage.isOfficial FROM `countrylanguage` JOIN country ON countrylanguage.CountryCode = country.Code From 7db3cf5dc2470e3e5323b17150d1488d8cb4e2b7 Mon Sep 17 00:00:00 2001 From: Sizolwakhe Leonard Mthimunye Date: Thu, 11 Sep 2025 00:29:48 +0200 Subject: [PATCH 5/7] creating session for contries response --- .../controllers/CountriesController.java | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/airpenthouse/GoTel/controllers/CountriesController.java b/src/main/java/org/airpenthouse/GoTel/controllers/CountriesController.java index 0db1ed8..788b75a 100644 --- a/src/main/java/org/airpenthouse/GoTel/controllers/CountriesController.java +++ b/src/main/java/org/airpenthouse/GoTel/controllers/CountriesController.java @@ -1,5 +1,6 @@ package org.airpenthouse.GoTel.controllers; +import jakarta.servlet.http.HttpSession; import org.airpenthouse.GoTel.services.country.CountriesService; import org.airpenthouse.GoTel.util.PropertiesUtilManager; import org.airpenthouse.GoTel.util.dto.binder.CountriesRequestCombiner; @@ -22,10 +23,11 @@ public class CountriesController { public CountriesService executor; @GetMapping("/getAllCountries") - public ResponseEntity> getAllCountries() { + public ResponseEntity> getAllCountries(HttpSession session) { CountriesService.SERVICE_HANDLER = "FIND_ALL_COUNTRIES"; CountriesExecutors.setMapper(mapper); Set entities = executor.initializeCountriesService(); + session.setAttribute("_getAllCountries",entities); if (entities.isEmpty()) { return ResponseEntity.notFound().build(); } else { @@ -34,13 +36,14 @@ public ResponseEntity> getAllCountries() } @GetMapping("/{memberUsername}/getAllCountries") - public ResponseEntity> membersGetAllCountries(@PathVariable String memberUsername, @RequestHeader(name = "x-auth-membership-token") String memberToken) { + public ResponseEntity> membersGetAllCountries(HttpSession session,@PathVariable String memberUsername, @RequestHeader(name = "x-auth-membership-token") String memberToken) { CountriesService.SERVICE_HANDLER = "FIND_ALL_COUNTRIES"; CountriesExecutors.setMapper(mapper); PropertiesUtilManager.setProperties("memberUsername", memberUsername); PropertiesUtilManager.setProperties("memberToken", memberToken); if (executor.checkMemberShipStatusAndTokenMatch()) { Set entities = executor.initializeCountriesService(); + session.setAttribute("_getAllCountriesMembers",entities); if (entities.isEmpty()) { return ResponseEntity.notFound().build(); } else { @@ -52,7 +55,7 @@ public ResponseEntity> membersGetAllCoun } @GetMapping("/{memberUsername}/getCountryByName/{countryName}") - public ResponseEntity> membersGetCountryByName(@PathVariable String countryName, @PathVariable String memberUsername, @RequestHeader(name = "x-auth-membership-token") String memberToken) { + public ResponseEntity> membersGetCountryByName(HttpSession session,@PathVariable String countryName, @PathVariable String memberUsername, @RequestHeader(name = "x-auth-membership-token") String memberToken) { CountriesService.SERVICE_HANDLER = "FIND_COUNTRY_BY_NAME"; CountriesExecutors.setMapper(mapper); PropertiesUtilManager.setProperties("memberUsername", memberUsername); @@ -60,6 +63,7 @@ public ResponseEntity> membersGetCountry PropertiesUtilManager.setProperties("memberToken", memberToken); if (executor.checkMemberShipStatusAndTokenMatch()) { Set entities = executor.initializeCountriesService(); + session.setAttribute("_getAllCountriesMembership",entities); if (entities.isEmpty()) { return ResponseEntity.notFound().build(); } else { @@ -71,24 +75,27 @@ public ResponseEntity> membersGetCountry } @GetMapping("/getCountryByName/{countryName}") - public ResponseEntity> getCountryByName(@PathVariable String countryName) { + public ResponseEntity> getCountryByName(HttpSession session,@PathVariable String countryName) { CountriesService.SERVICE_HANDLER = "FIND_COUNTRY_BY_NAME"; CountriesExecutors.setMapper(mapper); PropertiesUtilManager.setProperties("countryName", countryName); Set entities = executor.initializeCountriesService(); + session.setAttribute("_getAllCountries",entities); if (entities.isEmpty()) { return ResponseEntity.notFound().build(); + } else { return ResponseEntity.ok(entities); } } @GetMapping("/getCountryByContinent/{continentName}") - public ResponseEntity> getCountryByContinent(@PathVariable String continentName) { + public ResponseEntity> getCountryByContinent(HttpSession session,@PathVariable String continentName) { CountriesService.SERVICE_HANDLER = "FIND_COUNTRY_BY_CONTINENT"; CountriesExecutors.setMapper(mapper); PropertiesUtilManager.setProperties("continentName", continentName); Set entities = executor.initializeCountriesService(); + session.setAttribute("_getAllCountries",entities); if (entities.isEmpty()) { return ResponseEntity.notFound().build(); } else { @@ -97,7 +104,7 @@ public ResponseEntity> getCountryByConti } @GetMapping("/{memberUsername}/getCountryByRegion/{regionName}") - public ResponseEntity> memberGetCountryByRegion(@PathVariable String regionName, @PathVariable String memberUsername, @RequestHeader(name = "x-auth-membership-token") String memberToken) { + public ResponseEntity> memberGetCountryByRegion(HttpSession session,@PathVariable String regionName, @PathVariable String memberUsername, @RequestHeader(name = "x-auth-membership-token") String memberToken) { CountriesService.SERVICE_HANDLER = "FIND_COUNTRY_BY_REGION"; CountriesExecutors.setMapper(mapper); PropertiesUtilManager.setProperties("regionName", regionName); @@ -105,6 +112,7 @@ public ResponseEntity> memberGetCountryB PropertiesUtilManager.setProperties("memberUsername", memberUsername); if (executor.checkMemberShipStatusAndTokenMatch()) { Set entities = executor.initializeCountriesService(); + session.setAttribute("_getAllCountriesMembership",entities); if (entities.isEmpty()) { return ResponseEntity.notFound().build(); } else { @@ -116,7 +124,7 @@ public ResponseEntity> memberGetCountryB } @GetMapping("/{memberUsername}/getCountryByContinent/{continentName}") - public ResponseEntity> memberGetCountryByContinent(@PathVariable String continentName, @PathVariable String memberUsername, @RequestHeader String memberToken) { + public ResponseEntity> memberGetCountryByContinent(HttpSession session,@PathVariable String continentName, @PathVariable String memberUsername, @RequestHeader String memberToken) { CountriesService.SERVICE_HANDLER = "FIND_COUNTRY_BY_CONTINENT"; CountriesExecutors.setMapper(mapper); PropertiesUtilManager.setProperties("memberUsername", memberUsername); @@ -125,6 +133,7 @@ public ResponseEntity> memberGetCountryB if (executor.checkMemberShipStatusAndTokenMatch()) { Set entities = executor.initializeCountriesService(); + session.setAttribute("_getAllCountries",entities); if (entities.isEmpty()) { return ResponseEntity.notFound().build(); } else { @@ -136,11 +145,12 @@ public ResponseEntity> memberGetCountryB } @GetMapping("/getCountryByRegion/{regionName}") - public ResponseEntity> getCountryByRegion(@PathVariable String regionName) { + public ResponseEntity> getCountryByRegion(HttpSession session,@PathVariable String regionName) { CountriesService.SERVICE_HANDLER = "FIND_COUNTRY_BY_REGION"; CountriesExecutors.setMapper(mapper); PropertiesUtilManager.setProperties("regionName", regionName); Set entities = executor.initializeCountriesService(); + session.setAttribute("_getAllCountries",entities); if (entities.isEmpty()) { return ResponseEntity.notFound().build(); } else { From 003078aae75af9825a58db004c90abdf3efb2021 Mon Sep 17 00:00:00 2001 From: Sizolwakhe Leonard Mthimunye Date: Thu, 11 Sep 2025 00:32:13 +0200 Subject: [PATCH 6/7] make contries dto Serializable --- .../airpenthouse/GoTel/dtos/countries/CountriesRequest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/airpenthouse/GoTel/dtos/countries/CountriesRequest.java b/src/main/java/org/airpenthouse/GoTel/dtos/countries/CountriesRequest.java index 5b0fdfc..ef45707 100644 --- a/src/main/java/org/airpenthouse/GoTel/dtos/countries/CountriesRequest.java +++ b/src/main/java/org/airpenthouse/GoTel/dtos/countries/CountriesRequest.java @@ -5,9 +5,11 @@ import lombok.Getter; import org.airpenthouse.GoTel.util.dto.binder.CountriesRequestCombiner; +import java.io.Serializable; + @AllArgsConstructor @Getter -public class CountriesRequest implements CountriesRequestCombiner { +public class CountriesRequest implements CountriesRequestCombiner, Serializable { @JsonProperty("country_name") private String countryName; @JsonProperty("_country_region") From 4d132814bd4509e7c3601293c89d9aed41a44116 Mon Sep 17 00:00:00 2001 From: Sizolwakhe Leonard Mthimunye Date: Thu, 11 Sep 2025 00:33:01 +0200 Subject: [PATCH 7/7] caching our services response --- .../GoTel/services/country/CountriesService.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/org/airpenthouse/GoTel/services/country/CountriesService.java b/src/main/java/org/airpenthouse/GoTel/services/country/CountriesService.java index 9f7315d..e35b0a5 100644 --- a/src/main/java/org/airpenthouse/GoTel/services/country/CountriesService.java +++ b/src/main/java/org/airpenthouse/GoTel/services/country/CountriesService.java @@ -5,6 +5,7 @@ import org.airpenthouse.GoTel.util.dto.binder.CountriesRequestCombiner; import org.airpenthouse.GoTel.util.executors.CountriesExecutors; import org.airpenthouse.GoTel.util.mappers.CountriesMapper; +import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import java.util.*; @@ -20,6 +21,7 @@ public class CountriesService extends CountriesExecutors implements Callable getAllCountries() { ENTITY_TRIGGER = "FIND_ALL_COUNTRIES"; return getRequest(); @@ -35,16 +37,19 @@ private Set getRequest() { return initializeCountriesEntity().stream().map(mapper::mapper).collect(Collectors.toSet()); } + @Cacheable("countriesDataByName") private Set getCountryByName() { ENTITY_TRIGGER = "FIND_COUNTRY_BY_NAME"; return getRequest(); } + @Cacheable("CountriesDataContinent") private Set getCountryByContinent() { ENTITY_TRIGGER = "FIND_COUNTRY_BY_CONTINENT"; return getRequest(); } + @Cacheable("CountriesDataByRegion") private Set getCountryByRegion() { ENTITY_TRIGGER = "FIND_COUNTRY_BY_REGION"; return getRequest();