From 401a9b9baab7e0659c5668df31c464b1b92eeb94 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Wed, 25 Sep 2024 22:37:08 +0200 Subject: [PATCH 01/48] feat: add domain classes --- src/main/java/com/javarush/domain/City.java | 22 +++++++++++++++ .../java/com/javarush/domain/Continent.java | 11 ++++++++ .../com/javarush/domain/CountryLanguage.java | 27 +++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 src/main/java/com/javarush/domain/City.java create mode 100644 src/main/java/com/javarush/domain/Continent.java create mode 100644 src/main/java/com/javarush/domain/CountryLanguage.java diff --git a/src/main/java/com/javarush/domain/City.java b/src/main/java/com/javarush/domain/City.java new file mode 100644 index 0000000..017217e --- /dev/null +++ b/src/main/java/com/javarush/domain/City.java @@ -0,0 +1,22 @@ +package com.javarush.domain; + +import jakarta.persistence.*; +import lombok.Data; + +@Data +@Entity +@Table(name = "city") +public class City { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + @ManyToOne + @JoinColumn(name = "country_id") + private Country countryId; + @Column(name = "name") + private String name; + @Column(name = "district") + private String district; + @Column(name = "population") + private int population; +} diff --git a/src/main/java/com/javarush/domain/Continent.java b/src/main/java/com/javarush/domain/Continent.java new file mode 100644 index 0000000..14a8593 --- /dev/null +++ b/src/main/java/com/javarush/domain/Continent.java @@ -0,0 +1,11 @@ +package com.javarush.domain; + +public enum Continent { + ASIA, + EUROPE, + NORTH_AMERICA, + AFRICA, + OCEANIA, + ANTARCTICA, + SOUTH_AMERICA +} diff --git a/src/main/java/com/javarush/domain/CountryLanguage.java b/src/main/java/com/javarush/domain/CountryLanguage.java new file mode 100644 index 0000000..f1de7e3 --- /dev/null +++ b/src/main/java/com/javarush/domain/CountryLanguage.java @@ -0,0 +1,27 @@ +package com.javarush.domain; + +import jakarta.persistence.*; +import lombok.Data; +import org.hibernate.annotations.Type; + +import java.math.BigDecimal; + +@Data +@Entity +@Table(name = "country_language") +public class CountryLanguage { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + @ManyToOne + @JoinColumn(name = "country_id") + private Country countryId; + @Column(name = "language") + private String language; + @Column(name = "is_official", columnDefinition = "BIT") + @Type(type = "org.hibernate.type.NumericBooleanType") + private Boolean isOfficial; + @Column(name = "percentage") + private BigDecimal percentage; + +} From 2776890ef984dcead79a2b5b3fa52e567bb2e3e0 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Wed, 25 Sep 2024 22:41:04 +0200 Subject: [PATCH 02/48] feat: configuration for database --- .../com/javarush/config/DatabaseConfig.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/main/java/com/javarush/config/DatabaseConfig.java diff --git a/src/main/java/com/javarush/config/DatabaseConfig.java b/src/main/java/com/javarush/config/DatabaseConfig.java new file mode 100644 index 0000000..827a46a --- /dev/null +++ b/src/main/java/com/javarush/config/DatabaseConfig.java @@ -0,0 +1,31 @@ +package com.javarush.config; + +import com.javarush.domain.City; +import com.javarush.domain.Country; +import com.javarush.domain.CountryLanguage; +import org.hibernate.SessionFactory; +import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.Environment; + +import java.util.Properties; + +public class DatabaseConfig { + public SessionFactory prepareRelationalDb() { + Properties properties = new Properties(); + properties.put(Environment.DIALECT, "org.hibernate.dialect.MySQL8Dialect"); + properties.put(Environment.DRIVER, "com.p6spy.engine.spy.P6SpyDriver"); + properties.put(Environment.URL, "jdbc:p6spy:mysql://localhost:3306/world"); + properties.put(Environment.USER, "root"); + properties.put(Environment.PASS, "root"); + properties.put(Environment.CURRENT_SESSION_CONTEXT_CLASS, "thread"); + properties.put(Environment.HBM2DDL_AUTO, "validate"); + properties.put(Environment.STATEMENT_BATCH_SIZE, "100"); + + return new Configuration() + .addAnnotatedClass(City.class) + .addAnnotatedClass(Country.class) + .addAnnotatedClass(CountryLanguage.class) + .addProperties(properties) + .buildSessionFactory(); + } +} From 9235dbab0c6a05c3107b103d1853b50dd4feff68 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Wed, 25 Sep 2024 22:41:22 +0200 Subject: [PATCH 03/48] feat: configuration for redis --- .../java/com/javarush/config/RedisConfig.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/main/java/com/javarush/config/RedisConfig.java diff --git a/src/main/java/com/javarush/config/RedisConfig.java b/src/main/java/com/javarush/config/RedisConfig.java new file mode 100644 index 0000000..44b7ced --- /dev/null +++ b/src/main/java/com/javarush/config/RedisConfig.java @@ -0,0 +1,15 @@ +package com.javarush.config; + +import io.lettuce.core.RedisClient; +import io.lettuce.core.RedisURI; +import io.lettuce.core.api.StatefulRedisConnection; + +public class RedisConfig { + public RedisClient prepareRedisClient() { + RedisClient redisClient = RedisClient.create(RedisURI.create("localhost", 6379)); + try (StatefulRedisConnection connection = redisClient.connect()) { + System.out.println("\nConnected to Redis\n"); + } + return redisClient; + } +} From 35a31ea2945a1b3e439b5d82b0eb80952b04b1be Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Wed, 25 Sep 2024 22:43:01 +0200 Subject: [PATCH 04/48] feat: method of getting all data from mysql --- src/main/java/com/javarush/Main.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/main/java/com/javarush/Main.java diff --git a/src/main/java/com/javarush/Main.java b/src/main/java/com/javarush/Main.java new file mode 100644 index 0000000..8e88c71 --- /dev/null +++ b/src/main/java/com/javarush/Main.java @@ -0,0 +1,19 @@ +package com.javarush; + +import com.javarush.config.DatabaseConfig; +import com.javarush.config.RedisConfig; +import io.lettuce.core.RedisClient; +import org.hibernate.SessionFactory; + +public class Main { + private final SessionFactory sessionFactory; + private final RedisClient redisClient; + + public Main() { + DatabaseConfig databaseConfig = new DatabaseConfig(); + sessionFactory = databaseConfig.prepareRelationalDb(); + RedisConfig redisConfig = new RedisConfig(); + redisClient = redisConfig.prepareRedisClient(); + } + +} From 875e3cb67194f1deec90a93ffc4b38716898a8eb Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Wed, 25 Sep 2024 22:53:13 +0200 Subject: [PATCH 05/48] feat: add country services --- .../javarush/services/CountryServices.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/main/java/com/javarush/services/CountryServices.java diff --git a/src/main/java/com/javarush/services/CountryServices.java b/src/main/java/com/javarush/services/CountryServices.java new file mode 100644 index 0000000..5a80e0c --- /dev/null +++ b/src/main/java/com/javarush/services/CountryServices.java @@ -0,0 +1,22 @@ +package com.javarush.services; + +import com.javarush.domain.Country; +import org.hibernate.SessionFactory; +import org.hibernate.query.Query; + +import java.util.List; + +public class CountryServices { + private final SessionFactory sessionFactory; + + public CountryServices(SessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + } + + public List getAll() { + Query query = sessionFactory.getCurrentSession().createQuery("select c from Country c join fetch c.languages", Country.class); + return query.list(); + } + + //cover by tests, loggers +} From 04e70ae7b7cbe524fa6e368553c0b94ea97d6754 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Wed, 25 Sep 2024 23:18:49 +0200 Subject: [PATCH 06/48] feat: add redis services --- .../com/javarush/services/RedisServices.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/main/java/com/javarush/services/RedisServices.java diff --git a/src/main/java/com/javarush/services/RedisServices.java b/src/main/java/com/javarush/services/RedisServices.java new file mode 100644 index 0000000..e0d10b5 --- /dev/null +++ b/src/main/java/com/javarush/services/RedisServices.java @@ -0,0 +1,47 @@ +package com.javarush.services; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.javarush.redis.CityCountry; +import io.lettuce.core.RedisClient; +import io.lettuce.core.api.StatefulRedisConnection; +import io.lettuce.core.api.sync.RedisStringCommands; + +import java.util.List; + +public class RedisServices { + private final RedisClient redisClient; + private final ObjectMapper mapper; + + public RedisServices(RedisClient redisClient) { + this.redisClient = redisClient; + this.mapper = new ObjectMapper(); + } + + public void pushToRedis(List data) { + try (StatefulRedisConnection connection = redisClient.connect()) { + RedisStringCommands sync = connection.sync(); + for (CityCountry cityCountry : data) { + try { + sync.set(String.valueOf(cityCountry.getId()), mapper.writeValueAsString(cityCountry)); + } catch (JsonProcessingException e) { + e.printStackTrace(System.out); + } + } + } + } + + public void testRedisData(List ids) { + try (StatefulRedisConnection connection = redisClient.connect()) { + RedisStringCommands sync = connection.sync(); + for (Integer id : ids) { + String value = sync.get(String.valueOf(id)); + try { + mapper.readValue(value, CityCountry.class); + } catch (JsonProcessingException e) { + e.printStackTrace(System.out); + } + } + } + } +} From f826fc8cc42578537e6ff135c9db84c4be5eb661 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Thu, 26 Sep 2024 10:19:15 +0200 Subject: [PATCH 07/48] feat: add city services --- .../com/javarush/services/CityServices.java | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/main/java/com/javarush/services/CityServices.java diff --git a/src/main/java/com/javarush/services/CityServices.java b/src/main/java/com/javarush/services/CityServices.java new file mode 100644 index 0000000..641b49c --- /dev/null +++ b/src/main/java/com/javarush/services/CityServices.java @@ -0,0 +1,72 @@ +package com.javarush.services; + +import com.javarush.domain.City; +import com.javarush.domain.Country; +import com.javarush.domain.CountryLanguage; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.query.Query; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +public class CityServices { + private final SessionFactory sessionFactory; + private final CountryServices countryServices; + private static final Logger LOGGER = LoggerFactory.getLogger(CountryServices.class); + + public CityServices(SessionFactory sessionFactory, CountryServices countryServices) { + this.sessionFactory = sessionFactory; + this.countryServices = countryServices; + } + + public List getItems(int offset, int limit) { + Query query = sessionFactory.getCurrentSession().createQuery("select c from City c", City.class); + query.setFirstResult(offset); + query.setMaxResults(limit); + return query.list(); + } + + public int getTotalCount() { + Query query = sessionFactory.getCurrentSession().createQuery("select count(c) from City c", Long.class); + return Math.toIntExact(query.uniqueResult()); + } + + public City getById(Integer id) { + Query query = sessionFactory.getCurrentSession().createQuery("select c from City c join fetch c.countryId where c.id = :ID", City.class); + query.setParameter("ID", id); + return query.getSingleResult(); + } + + public void testMysqlData(List ids) { + try (Session session = sessionFactory.getCurrentSession()) { + session.beginTransaction(); + for (Integer id : ids) { + City city = getById(id); + Set languages = city.getCountryId().getLanguages(); + } + session.getTransaction().commit(); + } + } + + public List fetchData() { + try (Session session = sessionFactory.getCurrentSession()) { + List allCities = new ArrayList<>(); + session.beginTransaction(); + + List countries = countryServices.getAll(); + + int totalCount = getTotalCount(); + int step = 500; + for (int i = 0; i < totalCount; i += step) { + allCities.addAll(getItems(i, step)); + } + session.getTransaction().commit(); + return allCities; + } + } + //cover by tests, loggers +} From e03266231d26a3341223b412dc27e663480be6be Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Thu, 26 Sep 2024 11:54:44 +0200 Subject: [PATCH 08/48] feat: add classes with fields that often called in request --- .../java/com/javarush/redis/CityCountry.java | 34 +++++++++++++++++++ .../java/com/javarush/redis/Language.java | 12 +++++++ 2 files changed, 46 insertions(+) create mode 100644 src/main/java/com/javarush/redis/CityCountry.java create mode 100644 src/main/java/com/javarush/redis/Language.java diff --git a/src/main/java/com/javarush/redis/CityCountry.java b/src/main/java/com/javarush/redis/CityCountry.java new file mode 100644 index 0000000..907316a --- /dev/null +++ b/src/main/java/com/javarush/redis/CityCountry.java @@ -0,0 +1,34 @@ +package com.javarush.redis; + +import com.javarush.domain.Continent; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Set; + +@Data +public class CityCountry { + private Integer id; + + private String name; + + private String district; + + private Integer population; + + private String countryCode; + + private String alternativeCountryCode; + + private String countryName; + + private Continent continent; + + private String countryRegion; + + private BigDecimal countrySurfaceArea; + + private Integer countryPopulation; + + private Set languages; +} diff --git a/src/main/java/com/javarush/redis/Language.java b/src/main/java/com/javarush/redis/Language.java new file mode 100644 index 0000000..c91d80a --- /dev/null +++ b/src/main/java/com/javarush/redis/Language.java @@ -0,0 +1,12 @@ +package com.javarush.redis; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class Language { + private String language; + private Boolean isOfficial; + private BigDecimal percentage; +} From 0d8f3dff004b5149c89010738186d08586880798 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Thu, 26 Sep 2024 12:20:50 +0200 Subject: [PATCH 09/48] refactor: move non business logic to CityDataProcessing class --- .../com/javarush/services/CityServices.java | 63 +++++++------------ .../javarush/utils/CityDataProcessing.java | 54 ++++++++++++++++ 2 files changed, 77 insertions(+), 40 deletions(-) create mode 100644 src/main/java/com/javarush/utils/CityDataProcessing.java diff --git a/src/main/java/com/javarush/services/CityServices.java b/src/main/java/com/javarush/services/CityServices.java index 641b49c..dd26549 100644 --- a/src/main/java/com/javarush/services/CityServices.java +++ b/src/main/java/com/javarush/services/CityServices.java @@ -1,9 +1,6 @@ package com.javarush.services; import com.javarush.domain.City; -import com.javarush.domain.Country; -import com.javarush.domain.CountryLanguage; -import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.query.Query; import org.slf4j.Logger; @@ -11,7 +8,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Set; public class CityServices { private final SessionFactory sessionFactory; @@ -24,48 +20,35 @@ public CityServices(SessionFactory sessionFactory, CountryServices countryServic } public List getItems(int offset, int limit) { - Query query = sessionFactory.getCurrentSession().createQuery("select c from City c", City.class); - query.setFirstResult(offset); - query.setMaxResults(limit); - return query.list(); + try { + Query query = sessionFactory.getCurrentSession().createQuery("select c from City c", City.class); + query.setFirstResult(offset); + query.setMaxResults(limit); + return query.list(); + } catch (Exception e) { + LOGGER.error("Error fetching cities with offset {} and limit {}. Error message :: {}", offset, limit, e.getMessage()); + return new ArrayList<>(); + } } public int getTotalCount() { - Query query = sessionFactory.getCurrentSession().createQuery("select count(c) from City c", Long.class); - return Math.toIntExact(query.uniqueResult()); - } - - public City getById(Integer id) { - Query query = sessionFactory.getCurrentSession().createQuery("select c from City c join fetch c.countryId where c.id = :ID", City.class); - query.setParameter("ID", id); - return query.getSingleResult(); - } - - public void testMysqlData(List ids) { - try (Session session = sessionFactory.getCurrentSession()) { - session.beginTransaction(); - for (Integer id : ids) { - City city = getById(id); - Set languages = city.getCountryId().getLanguages(); - } - session.getTransaction().commit(); + try { + Query query = sessionFactory.getCurrentSession().createQuery("select count(c) from City c", Long.class); + return Math.toIntExact(query.uniqueResult()); + } catch (Exception e) { + LOGGER.error("Error fetching total city count. Error message :: {}", e.getMessage()); + return 0; } } - public List fetchData() { - try (Session session = sessionFactory.getCurrentSession()) { - List allCities = new ArrayList<>(); - session.beginTransaction(); - - List countries = countryServices.getAll(); - - int totalCount = getTotalCount(); - int step = 500; - for (int i = 0; i < totalCount; i += step) { - allCities.addAll(getItems(i, step)); - } - session.getTransaction().commit(); - return allCities; + public City getById(Integer id) { + try { + Query query = sessionFactory.getCurrentSession().createQuery("select c from City c join fetch c.countryId where c.id = :ID", City.class); + query.setParameter("ID", id); + return query.getSingleResult(); + } catch (Exception e) { + LOGGER.error("Error fetching city with ID {}. Error message :: {}", id, e.getMessage()); + return null; } } //cover by tests, loggers diff --git a/src/main/java/com/javarush/utils/CityDataProcessing.java b/src/main/java/com/javarush/utils/CityDataProcessing.java new file mode 100644 index 0000000..cd42525 --- /dev/null +++ b/src/main/java/com/javarush/utils/CityDataProcessing.java @@ -0,0 +1,54 @@ +package com.javarush.utils; + +import com.javarush.domain.City; +import com.javarush.domain.Country; +import com.javarush.domain.CountryLanguage; +import com.javarush.services.CityServices; +import com.javarush.services.CountryServices; +import org.hibernate.Session; +import org.hibernate.SessionFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +public class CityDataProcessing { + private final SessionFactory sessionFactory; + private final CityServices cityServices; + private final CountryServices countryServices; + + + public CityDataProcessing(SessionFactory sessionFactory, CityServices cityServices, CountryServices countryServices) { + this.sessionFactory = sessionFactory; + this.cityServices = cityServices; + this.countryServices = countryServices; + } + + public void testMysqlData(List ids) { + try (Session session = sessionFactory.getCurrentSession()) { + session.beginTransaction(); + for (Integer id : ids) { + City city = cityServices.getById(id); + Set languages = city.getCountryId().getLanguages(); + } + session.getTransaction().commit(); + } + } + + public List fetchData() { + try (Session session = sessionFactory.getCurrentSession()) { + List allCities = new ArrayList<>(); + session.beginTransaction(); + + List countries = countryServices.getAll(); + + int totalCount = cityServices.getTotalCount(); + int step = 500; + for (int i = 0; i < totalCount; i += step) { + allCities.addAll(cityServices.getItems(i, step)); + } + session.getTransaction().commit(); + return allCities; + } + } +} From 2d8f1febea3312ce891b44386fad5bdcc474a385 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Thu, 26 Sep 2024 12:21:18 +0200 Subject: [PATCH 10/48] refactor: move non business logic to CityDataProcessing class --- .../java/com/javarush/services/CountryServices.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/javarush/services/CountryServices.java b/src/main/java/com/javarush/services/CountryServices.java index 5a80e0c..cea24ec 100644 --- a/src/main/java/com/javarush/services/CountryServices.java +++ b/src/main/java/com/javarush/services/CountryServices.java @@ -3,19 +3,28 @@ import com.javarush.domain.Country; import org.hibernate.SessionFactory; import org.hibernate.query.Query; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.util.Collections; import java.util.List; public class CountryServices { private final SessionFactory sessionFactory; + private static final Logger LOGGER = LoggerFactory.getLogger(CountryServices.class); public CountryServices(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public List getAll() { - Query query = sessionFactory.getCurrentSession().createQuery("select c from Country c join fetch c.languages", Country.class); - return query.list(); + try { + Query query = sessionFactory.getCurrentSession().createQuery("select c from Country c join fetch c.languages", Country.class); + return query.list(); + } catch (Exception e) { + LOGGER.error("Error fetching countries", e); + return Collections.emptyList(); + } } //cover by tests, loggers From b776079f0e4787b9c51b01ef2243f2b6865418a1 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Thu, 26 Sep 2024 12:22:34 +0200 Subject: [PATCH 11/48] refactor: move non business logic to CityDataProcessing class --- src/main/java/com/javarush/services/CityServices.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/com/javarush/services/CityServices.java b/src/main/java/com/javarush/services/CityServices.java index dd26549..d4d6062 100644 --- a/src/main/java/com/javarush/services/CityServices.java +++ b/src/main/java/com/javarush/services/CityServices.java @@ -11,12 +11,10 @@ public class CityServices { private final SessionFactory sessionFactory; - private final CountryServices countryServices; private static final Logger LOGGER = LoggerFactory.getLogger(CountryServices.class); - public CityServices(SessionFactory sessionFactory, CountryServices countryServices) { + public CityServices(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; - this.countryServices = countryServices; } public List getItems(int offset, int limit) { From 647da176184286d7191eb1aa151cf43f1ee2f80c Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Thu, 26 Sep 2024 18:39:22 +0200 Subject: [PATCH 12/48] style: comments delete --- src/main/java/com/javarush/services/CityServices.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/javarush/services/CityServices.java b/src/main/java/com/javarush/services/CityServices.java index d4d6062..94042d1 100644 --- a/src/main/java/com/javarush/services/CityServices.java +++ b/src/main/java/com/javarush/services/CityServices.java @@ -49,5 +49,4 @@ public City getById(Integer id) { return null; } } - //cover by tests, loggers } From 98a30a4625c5f6b6fd4577dd8bcea48fb4202435 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Thu, 26 Sep 2024 19:56:03 +0200 Subject: [PATCH 13/48] style: comments delete --- src/main/java/com/javarush/services/RedisServices.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/com/javarush/services/RedisServices.java b/src/main/java/com/javarush/services/RedisServices.java index e0d10b5..7094827 100644 --- a/src/main/java/com/javarush/services/RedisServices.java +++ b/src/main/java/com/javarush/services/RedisServices.java @@ -6,10 +6,13 @@ import io.lettuce.core.RedisClient; import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.sync.RedisStringCommands; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.List; public class RedisServices { + private static final Logger LOGGER = LoggerFactory.getLogger(CountryServices.class); private final RedisClient redisClient; private final ObjectMapper mapper; @@ -25,6 +28,7 @@ public void pushToRedis(List data) { try { sync.set(String.valueOf(cityCountry.getId()), mapper.writeValueAsString(cityCountry)); } catch (JsonProcessingException e) { + LOGGER.error("Failed push to redis. Error message :: {}", e.getMessage()); e.printStackTrace(System.out); } } @@ -39,9 +43,12 @@ public void testRedisData(List ids) { try { mapper.readValue(value, CityCountry.class); } catch (JsonProcessingException e) { + LOGGER.error("Error message :: {}", e.getMessage()); e.printStackTrace(System.out); } } + }catch(Exception e) { + LOGGER.error("Error connecting to Redis. Error Message :: {}", e.getMessage()); } } } From e7acccf2b5ae8d2857b9cdc4f4bf22fe6a187c64 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Thu, 26 Sep 2024 19:56:07 +0200 Subject: [PATCH 14/48] style: comments delete --- src/main/java/com/javarush/services/CityServices.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/javarush/services/CityServices.java b/src/main/java/com/javarush/services/CityServices.java index 94042d1..1ca6171 100644 --- a/src/main/java/com/javarush/services/CityServices.java +++ b/src/main/java/com/javarush/services/CityServices.java @@ -11,10 +11,12 @@ public class CityServices { private final SessionFactory sessionFactory; + private final CountryServices countryServices; private static final Logger LOGGER = LoggerFactory.getLogger(CountryServices.class); - public CityServices(SessionFactory sessionFactory) { + public CityServices(SessionFactory sessionFactory, CountryServices countryServices) { this.sessionFactory = sessionFactory; + this.countryServices = countryServices; } public List getItems(int offset, int limit) { From 44a069234d0679f7e3aa51e23ef82e67912d86e5 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Thu, 26 Sep 2024 19:57:00 +0200 Subject: [PATCH 15/48] feat: add city-country transformer --- .../CityCountryTransformerService.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/main/java/com/javarush/services/CityCountryTransformerService.java diff --git a/src/main/java/com/javarush/services/CityCountryTransformerService.java b/src/main/java/com/javarush/services/CityCountryTransformerService.java new file mode 100644 index 0000000..4eb8e95 --- /dev/null +++ b/src/main/java/com/javarush/services/CityCountryTransformerService.java @@ -0,0 +1,43 @@ +package com.javarush.services; + +import com.javarush.domain.City; +import com.javarush.domain.Country; +import com.javarush.domain.CountryLanguage; +import com.javarush.redis.CityCountry; +import com.javarush.redis.Language; + +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class CityCountryTransformerService { + public List transformData(List cities) { + return cities.stream().map(city -> { + CityCountry res = new CityCountry(); + res.setId(city.getId()); + res.setName(city.getName()); + res.setPopulation(city.getPopulation()); + res.setDistrict(city.getDistrict()); + + Country country = city.getCountryId(); + res.setAlternativeCountryCode(country.getCode2()); + res.setContinent(country.getContinent()); + res.setCountryCode(country.getCode()); + res.setCountryName(country.getName()); + res.setCountryPopulation(country.getPopulation()); + res.setCountryRegion(country.getRegion()); + res.setCountrySurfaceArea(country.getSurfaceArea()); + Set countryLanguages = country.getLanguages(); + Set languages = countryLanguages.stream().map(cl -> { + Language language = new Language(); + language.setLanguage(cl.getLanguage()); + language.setIsOfficial(cl.getIsOfficial()); + language.setPercentage(cl.getPercentage()); + return language; + }).collect(Collectors.toSet()); + res.setLanguages(languages); + + return res; + }).collect(Collectors.toList()); + } +} From 17ab566dac22dca8c9122cb31dad1864597ba161 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Thu, 26 Sep 2024 19:58:45 +0200 Subject: [PATCH 16/48] feat: build feat --- src/main/java/com/javarush/Main.java | 50 ++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/main/java/com/javarush/Main.java b/src/main/java/com/javarush/Main.java index 8e88c71..266d117 100644 --- a/src/main/java/com/javarush/Main.java +++ b/src/main/java/com/javarush/Main.java @@ -2,9 +2,20 @@ import com.javarush.config.DatabaseConfig; import com.javarush.config.RedisConfig; +import com.javarush.domain.City; +import com.javarush.redis.CityCountry; +import com.javarush.services.CityCountryTransformerService; +import com.javarush.services.CityServices; +import com.javarush.services.CountryServices; +import com.javarush.services.RedisServices; +import com.javarush.utils.CityDataProcessing; import io.lettuce.core.RedisClient; import org.hibernate.SessionFactory; +import java.util.List; + +import static java.util.Objects.nonNull; + public class Main { private final SessionFactory sessionFactory; private final RedisClient redisClient; @@ -16,4 +27,43 @@ public Main() { redisClient = redisConfig.prepareRedisClient(); } + private void shutdown() { + if (nonNull(sessionFactory)) { + sessionFactory.close(); + } + if (nonNull(redisClient)) { + redisClient.shutdown(); + } + } + + public static void main(String[] args) { + Main main = new Main(); + RedisServices redisServices = new RedisServices(main.redisClient); + + CountryServices countryServices = new CountryServices(main.sessionFactory); + CityServices cityServices = new CityServices(main.sessionFactory, countryServices); + CityCountryTransformerService transformer = new CityCountryTransformerService(); + CityDataProcessing cityDataProcessing = new CityDataProcessing(main.sessionFactory, cityServices, countryServices); + + List allCities = cityDataProcessing.fetchData(); + List preparedData = transformer.transformData(allCities); + redisServices.pushToRedis(preparedData); + main.sessionFactory.getCurrentSession().close(); + + List ids = List.of(3, 2545, 123, 4, 189, 89, 3458, 1189, 10, 102); + + long startRedis = System.currentTimeMillis(); + redisServices.testRedisData(ids); + long stopRedis = System.currentTimeMillis(); + + long startMysql = System.currentTimeMillis(); + cityDataProcessing.testMysqlData(ids); + long stopMysql = System.currentTimeMillis(); + + System.out.printf("%s:\t%d ms\n", "Redis", (stopRedis - startRedis)); + System.out.printf("%s:\t%d ms\n", "MySQL", (stopMysql - startMysql)); + + main.shutdown(); + } + } From b948e6fa0529728eab22e840494f4762b2b493d4 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Thu, 26 Sep 2024 19:59:00 +0200 Subject: [PATCH 17/48] test: tests add --- .../CityCountryTransformerServiceTest.java | 68 +++++++++++++ .../javarush/services/CityServicesTest.java | 97 +++++++++++++++++++ .../services/CountryServicesTest.java | 53 ++++++++++ .../javarush/services/RedisServicesTest.java | 69 +++++++++++++ 4 files changed, 287 insertions(+) create mode 100644 src/test/java/com/javarush/services/CityCountryTransformerServiceTest.java create mode 100644 src/test/java/com/javarush/services/CityServicesTest.java create mode 100644 src/test/java/com/javarush/services/CountryServicesTest.java create mode 100644 src/test/java/com/javarush/services/RedisServicesTest.java diff --git a/src/test/java/com/javarush/services/CityCountryTransformerServiceTest.java b/src/test/java/com/javarush/services/CityCountryTransformerServiceTest.java new file mode 100644 index 0000000..37a44dc --- /dev/null +++ b/src/test/java/com/javarush/services/CityCountryTransformerServiceTest.java @@ -0,0 +1,68 @@ +package com.javarush.services; + +import com.javarush.domain.City; +import com.javarush.domain.Continent; +import com.javarush.domain.Country; +import com.javarush.domain.CountryLanguage; +import com.javarush.redis.CityCountry; +import com.javarush.redis.Language; +import org.junit.jupiter.api.Test; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.*; + +class CityCountryTransformerServiceTest { + @Test + public void testTransformData() { + City city = new City(); + city.setId(1); + city.setName("Test City"); + city.setPopulation(100000); + city.setDistrict("Test District"); + + Country country = new Country(); + country.setCode("TC"); + country.setCode2("TCC"); + country.setContinent(Continent.ASIA); + country.setName("Test Country"); + country.setPopulation(5000000); + country.setRegion("Test Region"); + country.setSurfaceArea(new BigDecimal("12345.67")); + + CountryLanguage countryLanguage = new CountryLanguage(); + countryLanguage.setLanguage("Test Language"); + countryLanguage.setIsOfficial(true); + countryLanguage.setPercentage(new BigDecimal("99.9")); + + city.setCountryId(country); + country.setLanguages(Set.of(countryLanguage)); + + CityCountryTransformerService cityCountryService = new CityCountryTransformerService(); + List result = cityCountryService.transformData(List.of(city)); + + assertNotNull(result); + assertEquals(1, result.size()); + CityCountry cityCountry = result.get(0); + assertEquals(1, cityCountry.getId()); + assertEquals("Test City", cityCountry.getName()); + assertEquals(100000, cityCountry.getPopulation()); + assertEquals("Test District", cityCountry.getDistrict()); + assertEquals("TCC", cityCountry.getAlternativeCountryCode()); + assertEquals(Continent.ASIA, cityCountry.getContinent()); + assertEquals("TC", cityCountry.getCountryCode()); + assertEquals("Test Country", cityCountry.getCountryName()); + assertEquals(5000000, cityCountry.getCountryPopulation()); + assertEquals("Test Region", cityCountry.getCountryRegion()); + assertEquals(new BigDecimal("12345.67"), cityCountry.getCountrySurfaceArea()); + assertNotNull(cityCountry.getLanguages()); + assertEquals(1, cityCountry.getLanguages().size()); + Language language = cityCountry.getLanguages().iterator().next(); + assertEquals("Test Language", language.getLanguage()); + assertTrue(language.getIsOfficial()); + assertEquals(new BigDecimal("99.9"), language.getPercentage()); + } + +} \ No newline at end of file diff --git a/src/test/java/com/javarush/services/CityServicesTest.java b/src/test/java/com/javarush/services/CityServicesTest.java new file mode 100644 index 0000000..a74da27 --- /dev/null +++ b/src/test/java/com/javarush/services/CityServicesTest.java @@ -0,0 +1,97 @@ +package com.javarush.services; + +import static org.mockito.Mockito.*; +import static org.junit.jupiter.api.Assertions.*; + +import com.javarush.domain.City; +import com.javarush.domain.Country; +import org.hibernate.Transaction; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.query.Query; +import java.util.Arrays; +import java.util.List; +import java.util.ArrayList; + +public class CityServicesTest { + + @Mock + private SessionFactory sessionFactory; + + @Mock + private Session session; + + @Mock + private Transaction transaction; + + @Mock + private Query cityQuery; + + @Mock + private Query countQuery; + + @Mock + private CountryServices countryServices; + + @InjectMocks + private CityServices cityServices; + + @BeforeEach + public void setUp() { + MockitoAnnotations.openMocks(this); + when(sessionFactory.getCurrentSession()).thenReturn(session); + when(session.getTransaction()).thenReturn(transaction); + } + + @Test + public void testGetItems() { + City city1 = new City(); + City city2 = new City(); + List expectedCities = Arrays.asList(city1, city2); + + when(session.createQuery("select c from City c", City.class)).thenReturn(cityQuery); + when(cityQuery.setFirstResult(anyInt())).thenReturn(cityQuery); + when(cityQuery.setMaxResults(anyInt())).thenReturn(cityQuery); + when(cityQuery.list()).thenReturn(expectedCities); + + List actualCities = cityServices.getItems(0, 10); + + assertEquals(expectedCities, actualCities); + verify(session).createQuery("select c from City c", City.class); + verify(cityQuery).setFirstResult(0); + verify(cityQuery).setMaxResults(10); + verify(cityQuery).list(); + } + + @Test + public void testGetTotalCount() { + when(session.createQuery("select count(c) from City c", Long.class)).thenReturn(countQuery); + when(countQuery.uniqueResult()).thenReturn(100L); + + int totalCount = cityServices.getTotalCount(); + + assertEquals(100, totalCount); + verify(session).createQuery("select count(c) from City c", Long.class); + verify(countQuery).uniqueResult(); + } + + @Test + public void testGetById() { + City expectedCity = new City(); + when(session.createQuery("select c from City c join fetch c.countryId where c.id = :ID", City.class)).thenReturn(cityQuery); + when(cityQuery.setParameter("ID", 1)).thenReturn(cityQuery); + when(cityQuery.getSingleResult()).thenReturn(expectedCity); + + City actualCity = cityServices.getById(1); + + assertEquals(expectedCity, actualCity); + verify(session).createQuery("select c from City c join fetch c.countryId where c.id = :ID", City.class); + verify(cityQuery).setParameter("ID", 1); + verify(cityQuery).getSingleResult(); + } +} \ No newline at end of file diff --git a/src/test/java/com/javarush/services/CountryServicesTest.java b/src/test/java/com/javarush/services/CountryServicesTest.java new file mode 100644 index 0000000..8af6079 --- /dev/null +++ b/src/test/java/com/javarush/services/CountryServicesTest.java @@ -0,0 +1,53 @@ +package com.javarush.services; + +import static org.mockito.Mockito.*; +import static org.junit.jupiter.api.Assertions.*; + +import com.javarush.domain.Country; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.query.Query; +import java.util.Arrays; +import java.util.List; + +class CountryServicesTest { + @Mock + private SessionFactory sessionFactory; + + @Mock + private Session session; + + @Mock + private Query query; + + @InjectMocks + private CountryServices countryServices; + + @BeforeEach + public void setUp() { + MockitoAnnotations.openMocks(this); + when(sessionFactory.getCurrentSession()).thenReturn(session); + } + + @Test + public void testGetAll() { + Country country1 = new Country(); + Country country2 = new Country(); + List expectedCountries = Arrays.asList(country1, country2); + + when(session.createQuery("select c from Country c join fetch c.languages", Country.class)).thenReturn(query); + when(query.list()).thenReturn(expectedCountries); + + List actualCountries = countryServices.getAll(); + + assertEquals(expectedCountries, actualCountries); + verify(sessionFactory).getCurrentSession(); + verify(session).createQuery("select c from Country c join fetch c.languages", Country.class); + verify(query).list(); + } +} \ No newline at end of file diff --git a/src/test/java/com/javarush/services/RedisServicesTest.java b/src/test/java/com/javarush/services/RedisServicesTest.java new file mode 100644 index 0000000..043a0ab --- /dev/null +++ b/src/test/java/com/javarush/services/RedisServicesTest.java @@ -0,0 +1,69 @@ +package com.javarush.services; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.javarush.redis.CityCountry; +import io.lettuce.core.RedisClient; +import io.lettuce.core.api.StatefulRedisConnection; +import io.lettuce.core.api.sync.RedisCommands; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.List; + +import static org.mockito.Mockito.*; + +class RedisServicesTest { + @Mock + private RedisClient redisClient; + + @Mock + private StatefulRedisConnection connection; + + @Mock + private RedisCommands syncCommands; + + @InjectMocks + private RedisServices redisServices; + + private final ObjectMapper mapper = new ObjectMapper(); + + @BeforeEach + public void setUp() { + MockitoAnnotations.openMocks(this); + when(redisClient.connect()).thenReturn(connection); + when(connection.sync()).thenReturn(syncCommands); + } + + @Test + public void testPushToRedis() throws JsonProcessingException { + CityCountry cityCountry = new CityCountry(); + cityCountry.setId(1); + cityCountry.setName("Test City"); + + List data = List.of(cityCountry); + + redisServices.pushToRedis(data); + + verify(syncCommands, times(1)).set(eq("1"), eq(mapper.writeValueAsString(cityCountry))); + } + + @Test + public void testTestRedisData() throws JsonProcessingException { + CityCountry cityCountry = new CityCountry(); + cityCountry.setId(1); + cityCountry.setName("Test City"); + + String cityCountryJson = mapper.writeValueAsString(cityCountry); + when(syncCommands.get("1")).thenReturn(cityCountryJson); + + List ids = List.of(1); + + redisServices.testRedisData(ids); + + verify(syncCommands, times(1)).get("1"); + } +} \ No newline at end of file From e0bf1eaa78256298fb8584010ce4da27e88e4d3a Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Thu, 26 Sep 2024 20:01:10 +0200 Subject: [PATCH 18/48] style: remove comments --- src/main/java/com/javarush/services/CountryServices.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/javarush/services/CountryServices.java b/src/main/java/com/javarush/services/CountryServices.java index cea24ec..bbfbe60 100644 --- a/src/main/java/com/javarush/services/CountryServices.java +++ b/src/main/java/com/javarush/services/CountryServices.java @@ -26,6 +26,4 @@ public List getAll() { return Collections.emptyList(); } } - - //cover by tests, loggers } From 1c354a0e4824583e15dbb1647375ba10d1bc4b2e Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Thu, 26 Sep 2024 20:17:18 +0200 Subject: [PATCH 19/48] refactor: names refactor --- src/main/java/com/javarush/Main.java | 18 +++++++-------- .../{CityServices.java => CityService.java} | 10 ++++----- ...untryServices.java => CountryService.java} | 6 ++--- .../{RedisServices.java => RedisService.java} | 6 ++--- .../javarush/utils/CityDataProcessing.java | 22 +++++++++---------- .../CityCountryTransformerServiceTest.java | 3 ++- ...ServicesTest.java => CityServiceTest.java} | 18 +++++++-------- ...vicesTest.java => CountryServiceTest.java} | 9 ++++---- ...ervicesTest.java => RedisServiceTest.java} | 11 +++++----- 9 files changed, 53 insertions(+), 50 deletions(-) rename src/main/java/com/javarush/services/{CityServices.java => CityService.java} (88%) rename src/main/java/com/javarush/services/{CountryServices.java => CountryService.java} (87%) rename src/main/java/com/javarush/services/{RedisServices.java => RedisService.java} (95%) rename src/test/java/com/javarush/{services => }/CityCountryTransformerServiceTest.java (97%) rename src/test/java/com/javarush/{services/CityServicesTest.java => CityServiceTest.java} (87%) rename src/test/java/com/javarush/{services/CountryServicesTest.java => CountryServiceTest.java} (87%) rename src/test/java/com/javarush/{services/RedisServicesTest.java => RedisServiceTest.java} (89%) diff --git a/src/main/java/com/javarush/Main.java b/src/main/java/com/javarush/Main.java index 266d117..21fe43d 100644 --- a/src/main/java/com/javarush/Main.java +++ b/src/main/java/com/javarush/Main.java @@ -5,9 +5,9 @@ import com.javarush.domain.City; import com.javarush.redis.CityCountry; import com.javarush.services.CityCountryTransformerService; -import com.javarush.services.CityServices; -import com.javarush.services.CountryServices; -import com.javarush.services.RedisServices; +import com.javarush.services.CityService; +import com.javarush.services.CountryService; +import com.javarush.services.RedisService; import com.javarush.utils.CityDataProcessing; import io.lettuce.core.RedisClient; import org.hibernate.SessionFactory; @@ -38,22 +38,22 @@ private void shutdown() { public static void main(String[] args) { Main main = new Main(); - RedisServices redisServices = new RedisServices(main.redisClient); + RedisService redisService = new RedisService(main.redisClient); - CountryServices countryServices = new CountryServices(main.sessionFactory); - CityServices cityServices = new CityServices(main.sessionFactory, countryServices); + CountryService countryService = new CountryService(main.sessionFactory); + CityService cityService = new CityService(main.sessionFactory, countryService); CityCountryTransformerService transformer = new CityCountryTransformerService(); - CityDataProcessing cityDataProcessing = new CityDataProcessing(main.sessionFactory, cityServices, countryServices); + CityDataProcessing cityDataProcessing = new CityDataProcessing(main.sessionFactory, cityService, countryService); List allCities = cityDataProcessing.fetchData(); List preparedData = transformer.transformData(allCities); - redisServices.pushToRedis(preparedData); + redisService.pushToRedis(preparedData); main.sessionFactory.getCurrentSession().close(); List ids = List.of(3, 2545, 123, 4, 189, 89, 3458, 1189, 10, 102); long startRedis = System.currentTimeMillis(); - redisServices.testRedisData(ids); + redisService.testRedisData(ids); long stopRedis = System.currentTimeMillis(); long startMysql = System.currentTimeMillis(); diff --git a/src/main/java/com/javarush/services/CityServices.java b/src/main/java/com/javarush/services/CityService.java similarity index 88% rename from src/main/java/com/javarush/services/CityServices.java rename to src/main/java/com/javarush/services/CityService.java index 1ca6171..a04e960 100644 --- a/src/main/java/com/javarush/services/CityServices.java +++ b/src/main/java/com/javarush/services/CityService.java @@ -9,14 +9,14 @@ import java.util.ArrayList; import java.util.List; -public class CityServices { +public class CityService { private final SessionFactory sessionFactory; - private final CountryServices countryServices; - private static final Logger LOGGER = LoggerFactory.getLogger(CountryServices.class); + private final CountryService countryService; + private static final Logger LOGGER = LoggerFactory.getLogger(CountryService.class); - public CityServices(SessionFactory sessionFactory, CountryServices countryServices) { + public CityService(SessionFactory sessionFactory, CountryService countryService) { this.sessionFactory = sessionFactory; - this.countryServices = countryServices; + this.countryService = countryService; } public List getItems(int offset, int limit) { diff --git a/src/main/java/com/javarush/services/CountryServices.java b/src/main/java/com/javarush/services/CountryService.java similarity index 87% rename from src/main/java/com/javarush/services/CountryServices.java rename to src/main/java/com/javarush/services/CountryService.java index bbfbe60..bbb7dea 100644 --- a/src/main/java/com/javarush/services/CountryServices.java +++ b/src/main/java/com/javarush/services/CountryService.java @@ -9,11 +9,11 @@ import java.util.Collections; import java.util.List; -public class CountryServices { +public class CountryService { private final SessionFactory sessionFactory; - private static final Logger LOGGER = LoggerFactory.getLogger(CountryServices.class); + private static final Logger LOGGER = LoggerFactory.getLogger(CountryService.class); - public CountryServices(SessionFactory sessionFactory) { + public CountryService(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } diff --git a/src/main/java/com/javarush/services/RedisServices.java b/src/main/java/com/javarush/services/RedisService.java similarity index 95% rename from src/main/java/com/javarush/services/RedisServices.java rename to src/main/java/com/javarush/services/RedisService.java index 7094827..15d122d 100644 --- a/src/main/java/com/javarush/services/RedisServices.java +++ b/src/main/java/com/javarush/services/RedisService.java @@ -11,12 +11,12 @@ import java.util.List; -public class RedisServices { - private static final Logger LOGGER = LoggerFactory.getLogger(CountryServices.class); +public class RedisService { + private static final Logger LOGGER = LoggerFactory.getLogger(CountryService.class); private final RedisClient redisClient; private final ObjectMapper mapper; - public RedisServices(RedisClient redisClient) { + public RedisService(RedisClient redisClient) { this.redisClient = redisClient; this.mapper = new ObjectMapper(); } diff --git a/src/main/java/com/javarush/utils/CityDataProcessing.java b/src/main/java/com/javarush/utils/CityDataProcessing.java index cd42525..3e24b32 100644 --- a/src/main/java/com/javarush/utils/CityDataProcessing.java +++ b/src/main/java/com/javarush/utils/CityDataProcessing.java @@ -3,8 +3,8 @@ import com.javarush.domain.City; import com.javarush.domain.Country; import com.javarush.domain.CountryLanguage; -import com.javarush.services.CityServices; -import com.javarush.services.CountryServices; +import com.javarush.services.CityService; +import com.javarush.services.CountryService; import org.hibernate.Session; import org.hibernate.SessionFactory; @@ -14,21 +14,21 @@ public class CityDataProcessing { private final SessionFactory sessionFactory; - private final CityServices cityServices; - private final CountryServices countryServices; + private final CityService cityService; + private final CountryService countryService; - public CityDataProcessing(SessionFactory sessionFactory, CityServices cityServices, CountryServices countryServices) { + public CityDataProcessing(SessionFactory sessionFactory, CityService cityService, CountryService countryService) { this.sessionFactory = sessionFactory; - this.cityServices = cityServices; - this.countryServices = countryServices; + this.cityService = cityService; + this.countryService = countryService; } public void testMysqlData(List ids) { try (Session session = sessionFactory.getCurrentSession()) { session.beginTransaction(); for (Integer id : ids) { - City city = cityServices.getById(id); + City city = cityService.getById(id); Set languages = city.getCountryId().getLanguages(); } session.getTransaction().commit(); @@ -40,12 +40,12 @@ public List fetchData() { List allCities = new ArrayList<>(); session.beginTransaction(); - List countries = countryServices.getAll(); + List countries = countryService.getAll(); - int totalCount = cityServices.getTotalCount(); + int totalCount = cityService.getTotalCount(); int step = 500; for (int i = 0; i < totalCount; i += step) { - allCities.addAll(cityServices.getItems(i, step)); + allCities.addAll(cityService.getItems(i, step)); } session.getTransaction().commit(); return allCities; diff --git a/src/test/java/com/javarush/services/CityCountryTransformerServiceTest.java b/src/test/java/com/javarush/CityCountryTransformerServiceTest.java similarity index 97% rename from src/test/java/com/javarush/services/CityCountryTransformerServiceTest.java rename to src/test/java/com/javarush/CityCountryTransformerServiceTest.java index 37a44dc..1520aa0 100644 --- a/src/test/java/com/javarush/services/CityCountryTransformerServiceTest.java +++ b/src/test/java/com/javarush/CityCountryTransformerServiceTest.java @@ -1,4 +1,4 @@ -package com.javarush.services; +package com.javarush; import com.javarush.domain.City; import com.javarush.domain.Continent; @@ -6,6 +6,7 @@ import com.javarush.domain.CountryLanguage; import com.javarush.redis.CityCountry; import com.javarush.redis.Language; +import com.javarush.services.CityCountryTransformerService; import org.junit.jupiter.api.Test; import java.math.BigDecimal; diff --git a/src/test/java/com/javarush/services/CityServicesTest.java b/src/test/java/com/javarush/CityServiceTest.java similarity index 87% rename from src/test/java/com/javarush/services/CityServicesTest.java rename to src/test/java/com/javarush/CityServiceTest.java index a74da27..d7ff989 100644 --- a/src/test/java/com/javarush/services/CityServicesTest.java +++ b/src/test/java/com/javarush/CityServiceTest.java @@ -1,10 +1,11 @@ -package com.javarush.services; +package com.javarush; import static org.mockito.Mockito.*; import static org.junit.jupiter.api.Assertions.*; import com.javarush.domain.City; -import com.javarush.domain.Country; +import com.javarush.services.CityService; +import com.javarush.services.CountryService; import org.hibernate.Transaction; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -16,9 +17,8 @@ import org.hibernate.query.Query; import java.util.Arrays; import java.util.List; -import java.util.ArrayList; -public class CityServicesTest { +public class CityServiceTest { @Mock private SessionFactory sessionFactory; @@ -36,10 +36,10 @@ public class CityServicesTest { private Query countQuery; @Mock - private CountryServices countryServices; + private CountryService countryService; @InjectMocks - private CityServices cityServices; + private CityService cityService; @BeforeEach public void setUp() { @@ -59,7 +59,7 @@ public void testGetItems() { when(cityQuery.setMaxResults(anyInt())).thenReturn(cityQuery); when(cityQuery.list()).thenReturn(expectedCities); - List actualCities = cityServices.getItems(0, 10); + List actualCities = cityService.getItems(0, 10); assertEquals(expectedCities, actualCities); verify(session).createQuery("select c from City c", City.class); @@ -73,7 +73,7 @@ public void testGetTotalCount() { when(session.createQuery("select count(c) from City c", Long.class)).thenReturn(countQuery); when(countQuery.uniqueResult()).thenReturn(100L); - int totalCount = cityServices.getTotalCount(); + int totalCount = cityService.getTotalCount(); assertEquals(100, totalCount); verify(session).createQuery("select count(c) from City c", Long.class); @@ -87,7 +87,7 @@ public void testGetById() { when(cityQuery.setParameter("ID", 1)).thenReturn(cityQuery); when(cityQuery.getSingleResult()).thenReturn(expectedCity); - City actualCity = cityServices.getById(1); + City actualCity = cityService.getById(1); assertEquals(expectedCity, actualCity); verify(session).createQuery("select c from City c join fetch c.countryId where c.id = :ID", City.class); diff --git a/src/test/java/com/javarush/services/CountryServicesTest.java b/src/test/java/com/javarush/CountryServiceTest.java similarity index 87% rename from src/test/java/com/javarush/services/CountryServicesTest.java rename to src/test/java/com/javarush/CountryServiceTest.java index 8af6079..bed0237 100644 --- a/src/test/java/com/javarush/services/CountryServicesTest.java +++ b/src/test/java/com/javarush/CountryServiceTest.java @@ -1,9 +1,10 @@ -package com.javarush.services; +package com.javarush; import static org.mockito.Mockito.*; import static org.junit.jupiter.api.Assertions.*; import com.javarush.domain.Country; +import com.javarush.services.CountryService; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; @@ -15,7 +16,7 @@ import java.util.Arrays; import java.util.List; -class CountryServicesTest { +class CountryServiceTest { @Mock private SessionFactory sessionFactory; @@ -26,7 +27,7 @@ class CountryServicesTest { private Query query; @InjectMocks - private CountryServices countryServices; + private CountryService countryService; @BeforeEach public void setUp() { @@ -43,7 +44,7 @@ public void testGetAll() { when(session.createQuery("select c from Country c join fetch c.languages", Country.class)).thenReturn(query); when(query.list()).thenReturn(expectedCountries); - List actualCountries = countryServices.getAll(); + List actualCountries = countryService.getAll(); assertEquals(expectedCountries, actualCountries); verify(sessionFactory).getCurrentSession(); diff --git a/src/test/java/com/javarush/services/RedisServicesTest.java b/src/test/java/com/javarush/RedisServiceTest.java similarity index 89% rename from src/test/java/com/javarush/services/RedisServicesTest.java rename to src/test/java/com/javarush/RedisServiceTest.java index 043a0ab..410379b 100644 --- a/src/test/java/com/javarush/services/RedisServicesTest.java +++ b/src/test/java/com/javarush/RedisServiceTest.java @@ -1,8 +1,9 @@ -package com.javarush.services; +package com.javarush; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.javarush.redis.CityCountry; +import com.javarush.services.RedisService; import io.lettuce.core.RedisClient; import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.sync.RedisCommands; @@ -16,7 +17,7 @@ import static org.mockito.Mockito.*; -class RedisServicesTest { +class RedisServiceTest { @Mock private RedisClient redisClient; @@ -27,7 +28,7 @@ class RedisServicesTest { private RedisCommands syncCommands; @InjectMocks - private RedisServices redisServices; + private RedisService redisService; private final ObjectMapper mapper = new ObjectMapper(); @@ -46,7 +47,7 @@ public void testPushToRedis() throws JsonProcessingException { List data = List.of(cityCountry); - redisServices.pushToRedis(data); + redisService.pushToRedis(data); verify(syncCommands, times(1)).set(eq("1"), eq(mapper.writeValueAsString(cityCountry))); } @@ -62,7 +63,7 @@ public void testTestRedisData() throws JsonProcessingException { List ids = List.of(1); - redisServices.testRedisData(ids); + redisService.testRedisData(ids); verify(syncCommands, times(1)).get("1"); } From 721adee32c7df801a7a1ff717a02e8ad0a0eaac0 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Sat, 5 Oct 2024 14:37:38 +0200 Subject: [PATCH 20/48] fix: add other lombok annotation instead of @Data which don't cause errors --- src/main/java/com/javarush/domain/City.java | 8 ++++++-- src/main/java/com/javarush/domain/Country.java | 8 ++++++-- src/main/java/com/javarush/domain/CountryLanguage.java | 8 ++++++-- src/main/java/com/javarush/services/CityService.java | 3 +++ 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/javarush/domain/City.java b/src/main/java/com/javarush/domain/City.java index 017217e..bb94d2f 100644 --- a/src/main/java/com/javarush/domain/City.java +++ b/src/main/java/com/javarush/domain/City.java @@ -1,9 +1,13 @@ package com.javarush.domain; import jakarta.persistence.*; -import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; -@Data +@Getter +@Setter +@NoArgsConstructor @Entity @Table(name = "city") public class City { diff --git a/src/main/java/com/javarush/domain/Country.java b/src/main/java/com/javarush/domain/Country.java index c2194c3..8b0c731 100644 --- a/src/main/java/com/javarush/domain/Country.java +++ b/src/main/java/com/javarush/domain/Country.java @@ -1,12 +1,16 @@ package com.javarush.domain; import jakarta.persistence.*; -import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; import java.math.BigDecimal; import java.util.Set; -@Data +@Getter +@Setter +@NoArgsConstructor @Entity @Table(name = "country") public class Country { diff --git a/src/main/java/com/javarush/domain/CountryLanguage.java b/src/main/java/com/javarush/domain/CountryLanguage.java index f1de7e3..54bc880 100644 --- a/src/main/java/com/javarush/domain/CountryLanguage.java +++ b/src/main/java/com/javarush/domain/CountryLanguage.java @@ -1,12 +1,16 @@ package com.javarush.domain; import jakarta.persistence.*; -import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; import org.hibernate.annotations.Type; import java.math.BigDecimal; -@Data +@Getter +@Setter +@NoArgsConstructor @Entity @Table(name = "country_language") public class CountryLanguage { diff --git a/src/main/java/com/javarush/services/CityService.java b/src/main/java/com/javarush/services/CityService.java index a04e960..60d588c 100644 --- a/src/main/java/com/javarush/services/CityService.java +++ b/src/main/java/com/javarush/services/CityService.java @@ -21,6 +21,7 @@ public CityService(SessionFactory sessionFactory, CountryService countryService) public List getItems(int offset, int limit) { try { + System.out.println("HELLO from getItems"); Query query = sessionFactory.getCurrentSession().createQuery("select c from City c", City.class); query.setFirstResult(offset); query.setMaxResults(limit); @@ -33,6 +34,7 @@ public List getItems(int offset, int limit) { public int getTotalCount() { try { + System.out.println("HELLO from getTotal count"); Query query = sessionFactory.getCurrentSession().createQuery("select count(c) from City c", Long.class); return Math.toIntExact(query.uniqueResult()); } catch (Exception e) { @@ -43,6 +45,7 @@ public int getTotalCount() { public City getById(Integer id) { try { + System.out.println("HELLO from get by id"); Query query = sessionFactory.getCurrentSession().createQuery("select c from City c join fetch c.countryId where c.id = :ID", City.class); query.setParameter("ID", id); return query.getSingleResult(); From 933d76668a8d4fa48478b3d0d4a4d66e8ec541bc Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Sat, 5 Oct 2024 14:47:50 +0200 Subject: [PATCH 21/48] refactor: add better structure for domain classes --- src/main/java/com/javarush/domain/{ => entity}/City.java | 2 +- .../java/com/javarush/domain/{ => entity}/Country.java | 3 ++- .../com/javarush/domain/{ => entity}/CountryLanguage.java | 2 +- .../java/com/javarush/domain/{ => enums}/Continent.java | 2 +- src/main/java/com/javarush/redis/CityCountry.java | 2 +- .../javarush/services/CityCountryTransformerService.java | 6 +++--- src/main/java/com/javarush/services/CityService.java | 2 +- src/main/java/com/javarush/services/CountryService.java | 2 +- src/main/java/com/javarush/utils/CityDataProcessing.java | 6 +++--- .../com/javarush/CityCountryTransformerServiceTest.java | 8 ++++---- src/test/java/com/javarush/CityServiceTest.java | 2 +- src/test/java/com/javarush/CountryServiceTest.java | 2 +- 12 files changed, 20 insertions(+), 19 deletions(-) rename src/main/java/com/javarush/domain/{ => entity}/City.java (93%) rename src/main/java/com/javarush/domain/{ => entity}/Country.java (94%) rename src/main/java/com/javarush/domain/{ => entity}/CountryLanguage.java (95%) rename src/main/java/com/javarush/domain/{ => enums}/Continent.java (78%) diff --git a/src/main/java/com/javarush/domain/City.java b/src/main/java/com/javarush/domain/entity/City.java similarity index 93% rename from src/main/java/com/javarush/domain/City.java rename to src/main/java/com/javarush/domain/entity/City.java index bb94d2f..f1aef0c 100644 --- a/src/main/java/com/javarush/domain/City.java +++ b/src/main/java/com/javarush/domain/entity/City.java @@ -1,4 +1,4 @@ -package com.javarush.domain; +package com.javarush.domain.entity; import jakarta.persistence.*; import lombok.Getter; diff --git a/src/main/java/com/javarush/domain/Country.java b/src/main/java/com/javarush/domain/entity/Country.java similarity index 94% rename from src/main/java/com/javarush/domain/Country.java rename to src/main/java/com/javarush/domain/entity/Country.java index 8b0c731..720dc62 100644 --- a/src/main/java/com/javarush/domain/Country.java +++ b/src/main/java/com/javarush/domain/entity/Country.java @@ -1,5 +1,6 @@ -package com.javarush.domain; +package com.javarush.domain.entity; +import com.javarush.domain.enums.Continent; import jakarta.persistence.*; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/src/main/java/com/javarush/domain/CountryLanguage.java b/src/main/java/com/javarush/domain/entity/CountryLanguage.java similarity index 95% rename from src/main/java/com/javarush/domain/CountryLanguage.java rename to src/main/java/com/javarush/domain/entity/CountryLanguage.java index 54bc880..b56aa35 100644 --- a/src/main/java/com/javarush/domain/CountryLanguage.java +++ b/src/main/java/com/javarush/domain/entity/CountryLanguage.java @@ -1,4 +1,4 @@ -package com.javarush.domain; +package com.javarush.domain.entity; import jakarta.persistence.*; import lombok.Getter; diff --git a/src/main/java/com/javarush/domain/Continent.java b/src/main/java/com/javarush/domain/enums/Continent.java similarity index 78% rename from src/main/java/com/javarush/domain/Continent.java rename to src/main/java/com/javarush/domain/enums/Continent.java index 14a8593..7d8b583 100644 --- a/src/main/java/com/javarush/domain/Continent.java +++ b/src/main/java/com/javarush/domain/enums/Continent.java @@ -1,4 +1,4 @@ -package com.javarush.domain; +package com.javarush.domain.enums; public enum Continent { ASIA, diff --git a/src/main/java/com/javarush/redis/CityCountry.java b/src/main/java/com/javarush/redis/CityCountry.java index 907316a..5f64121 100644 --- a/src/main/java/com/javarush/redis/CityCountry.java +++ b/src/main/java/com/javarush/redis/CityCountry.java @@ -1,6 +1,6 @@ package com.javarush.redis; -import com.javarush.domain.Continent; +import com.javarush.domain.enums.Continent; import lombok.Data; import java.math.BigDecimal; diff --git a/src/main/java/com/javarush/services/CityCountryTransformerService.java b/src/main/java/com/javarush/services/CityCountryTransformerService.java index 4eb8e95..f744b87 100644 --- a/src/main/java/com/javarush/services/CityCountryTransformerService.java +++ b/src/main/java/com/javarush/services/CityCountryTransformerService.java @@ -1,8 +1,8 @@ package com.javarush.services; -import com.javarush.domain.City; -import com.javarush.domain.Country; -import com.javarush.domain.CountryLanguage; +import com.javarush.domain.entity.City; +import com.javarush.domain.entity.Country; +import com.javarush.domain.entity.CountryLanguage; import com.javarush.redis.CityCountry; import com.javarush.redis.Language; diff --git a/src/main/java/com/javarush/services/CityService.java b/src/main/java/com/javarush/services/CityService.java index 60d588c..489df3c 100644 --- a/src/main/java/com/javarush/services/CityService.java +++ b/src/main/java/com/javarush/services/CityService.java @@ -1,6 +1,6 @@ package com.javarush.services; -import com.javarush.domain.City; +import com.javarush.domain.entity.City; import org.hibernate.SessionFactory; import org.hibernate.query.Query; import org.slf4j.Logger; diff --git a/src/main/java/com/javarush/services/CountryService.java b/src/main/java/com/javarush/services/CountryService.java index bbb7dea..16dfe02 100644 --- a/src/main/java/com/javarush/services/CountryService.java +++ b/src/main/java/com/javarush/services/CountryService.java @@ -1,6 +1,6 @@ package com.javarush.services; -import com.javarush.domain.Country; +import com.javarush.domain.entity.Country; import org.hibernate.SessionFactory; import org.hibernate.query.Query; import org.slf4j.Logger; diff --git a/src/main/java/com/javarush/utils/CityDataProcessing.java b/src/main/java/com/javarush/utils/CityDataProcessing.java index 3e24b32..f7d5d06 100644 --- a/src/main/java/com/javarush/utils/CityDataProcessing.java +++ b/src/main/java/com/javarush/utils/CityDataProcessing.java @@ -1,8 +1,8 @@ package com.javarush.utils; -import com.javarush.domain.City; -import com.javarush.domain.Country; -import com.javarush.domain.CountryLanguage; +import com.javarush.domain.entity.City; +import com.javarush.domain.entity.Country; +import com.javarush.domain.entity.CountryLanguage; import com.javarush.services.CityService; import com.javarush.services.CountryService; import org.hibernate.Session; diff --git a/src/test/java/com/javarush/CityCountryTransformerServiceTest.java b/src/test/java/com/javarush/CityCountryTransformerServiceTest.java index 1520aa0..8ef37c3 100644 --- a/src/test/java/com/javarush/CityCountryTransformerServiceTest.java +++ b/src/test/java/com/javarush/CityCountryTransformerServiceTest.java @@ -1,9 +1,9 @@ package com.javarush; -import com.javarush.domain.City; -import com.javarush.domain.Continent; -import com.javarush.domain.Country; -import com.javarush.domain.CountryLanguage; +import com.javarush.domain.entity.City; +import com.javarush.domain.enums.Continent; +import com.javarush.domain.entity.Country; +import com.javarush.domain.entity.CountryLanguage; import com.javarush.redis.CityCountry; import com.javarush.redis.Language; import com.javarush.services.CityCountryTransformerService; diff --git a/src/test/java/com/javarush/CityServiceTest.java b/src/test/java/com/javarush/CityServiceTest.java index d7ff989..b70aa70 100644 --- a/src/test/java/com/javarush/CityServiceTest.java +++ b/src/test/java/com/javarush/CityServiceTest.java @@ -3,7 +3,7 @@ import static org.mockito.Mockito.*; import static org.junit.jupiter.api.Assertions.*; -import com.javarush.domain.City; +import com.javarush.domain.entity.City; import com.javarush.services.CityService; import com.javarush.services.CountryService; import org.hibernate.Transaction; diff --git a/src/test/java/com/javarush/CountryServiceTest.java b/src/test/java/com/javarush/CountryServiceTest.java index bed0237..88f7860 100644 --- a/src/test/java/com/javarush/CountryServiceTest.java +++ b/src/test/java/com/javarush/CountryServiceTest.java @@ -3,7 +3,7 @@ import static org.mockito.Mockito.*; import static org.junit.jupiter.api.Assertions.*; -import com.javarush.domain.Country; +import com.javarush.domain.entity.Country; import com.javarush.services.CountryService; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; From de7cd6c143016525e9d8f64bb98d2ed0180145eb Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Sat, 5 Oct 2024 14:51:36 +0200 Subject: [PATCH 22/48] feat: add CrudRepository --- .../com/javarush/repository/CrudRepository.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/main/java/com/javarush/repository/CrudRepository.java diff --git a/src/main/java/com/javarush/repository/CrudRepository.java b/src/main/java/com/javarush/repository/CrudRepository.java new file mode 100644 index 0000000..e505b40 --- /dev/null +++ b/src/main/java/com/javarush/repository/CrudRepository.java @@ -0,0 +1,13 @@ +package com.javarush.repository; + +import java.util.List; + +public interface CrudRepository { + T getById(I id); + + T save(T entity); + + void delete(I id); + + List getAll(); +} From 809dadffb88feb07baa2b6fd58cd237b0f78c9e5 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Sat, 5 Oct 2024 15:11:49 +0200 Subject: [PATCH 23/48] feat: add config class --- ...DatabaseConfig.java => HibernateUtil.java} | 27 ++++++++++++++----- .../java/com/javarush/config/RedisConfig.java | 15 ----------- 2 files changed, 21 insertions(+), 21 deletions(-) rename src/main/java/com/javarush/config/{DatabaseConfig.java => HibernateUtil.java} (56%) delete mode 100644 src/main/java/com/javarush/config/RedisConfig.java diff --git a/src/main/java/com/javarush/config/DatabaseConfig.java b/src/main/java/com/javarush/config/HibernateUtil.java similarity index 56% rename from src/main/java/com/javarush/config/DatabaseConfig.java rename to src/main/java/com/javarush/config/HibernateUtil.java index 827a46a..4907a7e 100644 --- a/src/main/java/com/javarush/config/DatabaseConfig.java +++ b/src/main/java/com/javarush/config/HibernateUtil.java @@ -1,16 +1,20 @@ package com.javarush.config; -import com.javarush.domain.City; -import com.javarush.domain.Country; -import com.javarush.domain.CountryLanguage; +import com.javarush.domain.entity.City; +import com.javarush.domain.entity.Country; +import com.javarush.domain.entity.CountryLanguage; +import io.lettuce.core.RedisClient; +import io.lettuce.core.RedisURI; +import io.lettuce.core.api.StatefulRedisConnection; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; import java.util.Properties; -public class DatabaseConfig { - public SessionFactory prepareRelationalDb() { +public class HibernateUtil { + public static SessionFactory prepareRelationalDb() { + final SessionFactory sessionFactory; Properties properties = new Properties(); properties.put(Environment.DIALECT, "org.hibernate.dialect.MySQL8Dialect"); properties.put(Environment.DRIVER, "com.p6spy.engine.spy.P6SpyDriver"); @@ -21,11 +25,22 @@ public SessionFactory prepareRelationalDb() { properties.put(Environment.HBM2DDL_AUTO, "validate"); properties.put(Environment.STATEMENT_BATCH_SIZE, "100"); - return new Configuration() + sessionFactory = new Configuration() .addAnnotatedClass(City.class) .addAnnotatedClass(Country.class) .addAnnotatedClass(CountryLanguage.class) .addProperties(properties) .buildSessionFactory(); + return sessionFactory; } + + public RedisClient prepareRedisClient() { + RedisClient redisClient = RedisClient.create(RedisURI.create("localhost", 6379)); + try (StatefulRedisConnection connection = redisClient.connect()) { + System.out.println("\nConnected to Redis\n"); + } + return redisClient; + } + + } diff --git a/src/main/java/com/javarush/config/RedisConfig.java b/src/main/java/com/javarush/config/RedisConfig.java deleted file mode 100644 index 44b7ced..0000000 --- a/src/main/java/com/javarush/config/RedisConfig.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.javarush.config; - -import io.lettuce.core.RedisClient; -import io.lettuce.core.RedisURI; -import io.lettuce.core.api.StatefulRedisConnection; - -public class RedisConfig { - public RedisClient prepareRedisClient() { - RedisClient redisClient = RedisClient.create(RedisURI.create("localhost", 6379)); - try (StatefulRedisConnection connection = redisClient.connect()) { - System.out.println("\nConnected to Redis\n"); - } - return redisClient; - } -} From 37ce77f37f741049b56ae25d7f489b72c80e6655 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Sat, 5 Oct 2024 16:12:39 +0200 Subject: [PATCH 24/48] feat: add repository classes --- .../javarush/repository/CityRepository.java | 52 ++++++++++++++++++ .../repository/CountryRepository.java | 53 +++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 src/main/java/com/javarush/repository/CityRepository.java create mode 100644 src/main/java/com/javarush/repository/CountryRepository.java diff --git a/src/main/java/com/javarush/repository/CityRepository.java b/src/main/java/com/javarush/repository/CityRepository.java new file mode 100644 index 0000000..578f7b2 --- /dev/null +++ b/src/main/java/com/javarush/repository/CityRepository.java @@ -0,0 +1,52 @@ +package com.javarush.repository; + +import com.javarush.config.HibernateUtil; +import com.javarush.domain.entity.City; +import com.javarush.services.CountryService; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +public class CityRepository implements CrudRepository{ + private final SessionFactory sessionFactory = HibernateUtil.prepareRelationalDb(); + private static final Logger LOGGER = LoggerFactory.getLogger(CountryService.class); + @Override + public City getById(Long id) { + try(Session session = sessionFactory.getCurrentSession()) { + return session.createQuery("select c from City c where c.id = :ID", City.class) + .setParameter("ID", id) + .getSingleResult(); + } + } + + @Override + public City save(City entity) { + try(Session session = sessionFactory.getCurrentSession()) { + session.beginTransaction(); + session.persist(entity); + session.getTransaction().commit(); + return entity; + } + } + + @Override + public void delete(Long id) { + try(Session session = sessionFactory.getCurrentSession()) { + session.beginTransaction(); + session.createQuery("delete from City c where c.id = :ID", City.class) + .setParameter("ID", id) + .executeUpdate(); + session.getTransaction().commit(); + } + } + + @Override + public List getAll() { + try(Session session = sessionFactory.getCurrentSession()) { + return session.createQuery("select c from City c", City.class).list(); + } + } +} diff --git a/src/main/java/com/javarush/repository/CountryRepository.java b/src/main/java/com/javarush/repository/CountryRepository.java new file mode 100644 index 0000000..f7b0f5c --- /dev/null +++ b/src/main/java/com/javarush/repository/CountryRepository.java @@ -0,0 +1,53 @@ +package com.javarush.repository; + +import com.javarush.config.HibernateUtil; +import com.javarush.domain.entity.Country; +import com.javarush.services.CountryService; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +public class CountryRepository implements CrudRepository { + private final SessionFactory sessionFactory = HibernateUtil.prepareRelationalDb(); + private static final Logger LOGGER = LoggerFactory.getLogger(CountryService.class); + + @Override + public Country getById(Long id) { + try(Session session = sessionFactory.getCurrentSession()) { + return session.createQuery("select c from Country c where c.id = :ID", Country.class) + .setParameter("ID", id) + .getSingleResult(); + } + } + + @Override + public Country save(Country entity) { + try(Session session = sessionFactory.getCurrentSession()) { + session.beginTransaction(); + session.persist(entity); + session.getTransaction().commit(); + return entity; + } + } + + @Override + public void delete(Long id) { + try (Session session = sessionFactory.getCurrentSession()) { + session.beginTransaction(); + session.createQuery("delete from Country c where c.id = :ID", Country.class) + .setParameter("ID", id) + .executeUpdate(); + session.getTransaction().commit(); + } + } + + @Override + public List getAll() { + try(Session session = sessionFactory.getCurrentSession()) { + return session.createQuery("select c from Country c join fetch c.languages", Country.class).list(); + } + } +} From c59626f13451294b099351c221ecdc2d2df60fc9 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Sat, 5 Oct 2024 19:19:45 +0200 Subject: [PATCH 25/48] feat: add more database queries --- .../javarush/repository/CityRepository.java | 52 ++++++++++++++----- .../repository/CountryRepository.java | 22 +++++--- .../javarush/repository/CrudRepository.java | 4 ++ 3 files changed, 57 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/javarush/repository/CityRepository.java b/src/main/java/com/javarush/repository/CityRepository.java index 578f7b2..8a84950 100644 --- a/src/main/java/com/javarush/repository/CityRepository.java +++ b/src/main/java/com/javarush/repository/CityRepository.java @@ -2,29 +2,29 @@ import com.javarush.config.HibernateUtil; import com.javarush.domain.entity.City; -import com.javarush.services.CountryService; import org.hibernate.Session; import org.hibernate.SessionFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.util.List; -public class CityRepository implements CrudRepository{ +public class CityRepository implements CrudRepository { private final SessionFactory sessionFactory = HibernateUtil.prepareRelationalDb(); - private static final Logger LOGGER = LoggerFactory.getLogger(CountryService.class); + @Override public City getById(Long id) { - try(Session session = sessionFactory.getCurrentSession()) { - return session.createQuery("select c from City c where c.id = :ID", City.class) + try (Session session = sessionFactory.getCurrentSession()) { + session.beginTransaction(); + City city = session.createQuery("select c from City c join fetch c.countryId where c.id = :ID", City.class) .setParameter("ID", id) - .getSingleResult(); + .uniqueResult(); + session.getTransaction().commit(); + return city; } } @Override public City save(City entity) { - try(Session session = sessionFactory.getCurrentSession()) { + try (Session session = sessionFactory.getCurrentSession()) { session.beginTransaction(); session.persist(entity); session.getTransaction().commit(); @@ -34,19 +34,45 @@ public City save(City entity) { @Override public void delete(Long id) { - try(Session session = sessionFactory.getCurrentSession()) { + try (Session session = sessionFactory.getCurrentSession()) { session.beginTransaction(); session.createQuery("delete from City c where c.id = :ID", City.class) - .setParameter("ID", id) - .executeUpdate(); + .setParameter("ID", id) + .executeUpdate(); session.getTransaction().commit(); } } @Override public List getAll() { + try (Session session = sessionFactory.getCurrentSession()) { + session.beginTransaction(); + List cityList = session.createQuery("select c from City c", City.class).list(); + session.getTransaction().commit(); + return cityList; + } + } + + @Override + public List getItems(int offset, int limit) { try(Session session = sessionFactory.getCurrentSession()) { - return session.createQuery("select c from City c", City.class).list(); + session.beginTransaction(); + List cityList = session.createQuery("select c from City c", City.class) + .setFirstResult(offset) + .setMaxResults(limit) + .list(); + session.getTransaction().commit(); + return cityList; + } + } + + @Override + public int getTotalCount() { + try(Session session = sessionFactory.getCurrentSession()) { + session.beginTransaction(); + int intExact = Math.toIntExact(session.createQuery("select count(c) from City c", Long.class).uniqueResult()); + session.getTransaction().commit(); + return intExact; } } } diff --git a/src/main/java/com/javarush/repository/CountryRepository.java b/src/main/java/com/javarush/repository/CountryRepository.java index f7b0f5c..0db4bd2 100644 --- a/src/main/java/com/javarush/repository/CountryRepository.java +++ b/src/main/java/com/javarush/repository/CountryRepository.java @@ -2,22 +2,18 @@ import com.javarush.config.HibernateUtil; import com.javarush.domain.entity.Country; -import com.javarush.services.CountryService; import org.hibernate.Session; import org.hibernate.SessionFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.util.List; public class CountryRepository implements CrudRepository { private final SessionFactory sessionFactory = HibernateUtil.prepareRelationalDb(); - private static final Logger LOGGER = LoggerFactory.getLogger(CountryService.class); @Override public Country getById(Long id) { - try(Session session = sessionFactory.getCurrentSession()) { - return session.createQuery("select c from Country c where c.id = :ID", Country.class) + try (Session session = sessionFactory.getCurrentSession()) { + return session.createQuery("select c from Country c join fetch c.languages where c.id = :ID", Country.class) .setParameter("ID", id) .getSingleResult(); } @@ -25,7 +21,7 @@ public Country getById(Long id) { @Override public Country save(Country entity) { - try(Session session = sessionFactory.getCurrentSession()) { + try (Session session = sessionFactory.getCurrentSession()) { session.beginTransaction(); session.persist(entity); session.getTransaction().commit(); @@ -46,8 +42,18 @@ public void delete(Long id) { @Override public List getAll() { - try(Session session = sessionFactory.getCurrentSession()) { + try (Session session = sessionFactory.getCurrentSession()) { return session.createQuery("select c from Country c join fetch c.languages", Country.class).list(); } } + + @Override + public List getItems(int offset, int limit) { + return List.of(); + } + + @Override + public int getTotalCount() { + return 0; + } } diff --git a/src/main/java/com/javarush/repository/CrudRepository.java b/src/main/java/com/javarush/repository/CrudRepository.java index e505b40..4461b32 100644 --- a/src/main/java/com/javarush/repository/CrudRepository.java +++ b/src/main/java/com/javarush/repository/CrudRepository.java @@ -10,4 +10,8 @@ public interface CrudRepository { void delete(I id); List getAll(); + + List getItems(int offset, int limit); + + int getTotalCount(); } From 9c0db6546e85b7e9b524fb93dc9c6d26e4cc95d3 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Sat, 5 Oct 2024 19:20:27 +0200 Subject: [PATCH 26/48] remove: remove unnecessary classes --- .../CityCountryTransformerService.java | 43 --------------- .../com/javarush/services/RedisService.java | 54 ------------------- .../javarush/utils/CityDataProcessing.java | 54 ------------------- .../CityCountryTransformerServiceTest.java | 4 +- 4 files changed, 2 insertions(+), 153 deletions(-) delete mode 100644 src/main/java/com/javarush/services/CityCountryTransformerService.java delete mode 100644 src/main/java/com/javarush/services/RedisService.java delete mode 100644 src/main/java/com/javarush/utils/CityDataProcessing.java diff --git a/src/main/java/com/javarush/services/CityCountryTransformerService.java b/src/main/java/com/javarush/services/CityCountryTransformerService.java deleted file mode 100644 index f744b87..0000000 --- a/src/main/java/com/javarush/services/CityCountryTransformerService.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.javarush.services; - -import com.javarush.domain.entity.City; -import com.javarush.domain.entity.Country; -import com.javarush.domain.entity.CountryLanguage; -import com.javarush.redis.CityCountry; -import com.javarush.redis.Language; - -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -public class CityCountryTransformerService { - public List transformData(List cities) { - return cities.stream().map(city -> { - CityCountry res = new CityCountry(); - res.setId(city.getId()); - res.setName(city.getName()); - res.setPopulation(city.getPopulation()); - res.setDistrict(city.getDistrict()); - - Country country = city.getCountryId(); - res.setAlternativeCountryCode(country.getCode2()); - res.setContinent(country.getContinent()); - res.setCountryCode(country.getCode()); - res.setCountryName(country.getName()); - res.setCountryPopulation(country.getPopulation()); - res.setCountryRegion(country.getRegion()); - res.setCountrySurfaceArea(country.getSurfaceArea()); - Set countryLanguages = country.getLanguages(); - Set languages = countryLanguages.stream().map(cl -> { - Language language = new Language(); - language.setLanguage(cl.getLanguage()); - language.setIsOfficial(cl.getIsOfficial()); - language.setPercentage(cl.getPercentage()); - return language; - }).collect(Collectors.toSet()); - res.setLanguages(languages); - - return res; - }).collect(Collectors.toList()); - } -} diff --git a/src/main/java/com/javarush/services/RedisService.java b/src/main/java/com/javarush/services/RedisService.java deleted file mode 100644 index 15d122d..0000000 --- a/src/main/java/com/javarush/services/RedisService.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.javarush.services; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.javarush.redis.CityCountry; -import io.lettuce.core.RedisClient; -import io.lettuce.core.api.StatefulRedisConnection; -import io.lettuce.core.api.sync.RedisStringCommands; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; - -public class RedisService { - private static final Logger LOGGER = LoggerFactory.getLogger(CountryService.class); - private final RedisClient redisClient; - private final ObjectMapper mapper; - - public RedisService(RedisClient redisClient) { - this.redisClient = redisClient; - this.mapper = new ObjectMapper(); - } - - public void pushToRedis(List data) { - try (StatefulRedisConnection connection = redisClient.connect()) { - RedisStringCommands sync = connection.sync(); - for (CityCountry cityCountry : data) { - try { - sync.set(String.valueOf(cityCountry.getId()), mapper.writeValueAsString(cityCountry)); - } catch (JsonProcessingException e) { - LOGGER.error("Failed push to redis. Error message :: {}", e.getMessage()); - e.printStackTrace(System.out); - } - } - } - } - - public void testRedisData(List ids) { - try (StatefulRedisConnection connection = redisClient.connect()) { - RedisStringCommands sync = connection.sync(); - for (Integer id : ids) { - String value = sync.get(String.valueOf(id)); - try { - mapper.readValue(value, CityCountry.class); - } catch (JsonProcessingException e) { - LOGGER.error("Error message :: {}", e.getMessage()); - e.printStackTrace(System.out); - } - } - }catch(Exception e) { - LOGGER.error("Error connecting to Redis. Error Message :: {}", e.getMessage()); - } - } -} diff --git a/src/main/java/com/javarush/utils/CityDataProcessing.java b/src/main/java/com/javarush/utils/CityDataProcessing.java deleted file mode 100644 index f7d5d06..0000000 --- a/src/main/java/com/javarush/utils/CityDataProcessing.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.javarush.utils; - -import com.javarush.domain.entity.City; -import com.javarush.domain.entity.Country; -import com.javarush.domain.entity.CountryLanguage; -import com.javarush.services.CityService; -import com.javarush.services.CountryService; -import org.hibernate.Session; -import org.hibernate.SessionFactory; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -public class CityDataProcessing { - private final SessionFactory sessionFactory; - private final CityService cityService; - private final CountryService countryService; - - - public CityDataProcessing(SessionFactory sessionFactory, CityService cityService, CountryService countryService) { - this.sessionFactory = sessionFactory; - this.cityService = cityService; - this.countryService = countryService; - } - - public void testMysqlData(List ids) { - try (Session session = sessionFactory.getCurrentSession()) { - session.beginTransaction(); - for (Integer id : ids) { - City city = cityService.getById(id); - Set languages = city.getCountryId().getLanguages(); - } - session.getTransaction().commit(); - } - } - - public List fetchData() { - try (Session session = sessionFactory.getCurrentSession()) { - List allCities = new ArrayList<>(); - session.beginTransaction(); - - List countries = countryService.getAll(); - - int totalCount = cityService.getTotalCount(); - int step = 500; - for (int i = 0; i < totalCount; i += step) { - allCities.addAll(cityService.getItems(i, step)); - } - session.getTransaction().commit(); - return allCities; - } - } -} diff --git a/src/test/java/com/javarush/CityCountryTransformerServiceTest.java b/src/test/java/com/javarush/CityCountryTransformerServiceTest.java index 8ef37c3..f0914c4 100644 --- a/src/test/java/com/javarush/CityCountryTransformerServiceTest.java +++ b/src/test/java/com/javarush/CityCountryTransformerServiceTest.java @@ -17,7 +17,7 @@ class CityCountryTransformerServiceTest { @Test - public void testTransformData() { + public void testInitialisation() { City city = new City(); city.setId(1); city.setName("Test City"); @@ -42,7 +42,7 @@ public void testTransformData() { country.setLanguages(Set.of(countryLanguage)); CityCountryTransformerService cityCountryService = new CityCountryTransformerService(); - List result = cityCountryService.transformData(List.of(city)); + List result = cityCountryService.initialisation(List.of(city)); assertNotNull(result); assertEquals(1, result.size()); From bdb103ae94c9a9f3d3f77d05229340ff1faf332d Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Sat, 5 Oct 2024 19:20:53 +0200 Subject: [PATCH 27/48] feat: add customize exceptions --- .../java/com/javarush/domain/exceptions/CityNotFound.java | 7 +++++++ .../com/javarush/domain/exceptions/CountryException.java | 7 +++++++ 2 files changed, 14 insertions(+) create mode 100644 src/main/java/com/javarush/domain/exceptions/CityNotFound.java create mode 100644 src/main/java/com/javarush/domain/exceptions/CountryException.java diff --git a/src/main/java/com/javarush/domain/exceptions/CityNotFound.java b/src/main/java/com/javarush/domain/exceptions/CityNotFound.java new file mode 100644 index 0000000..c979d13 --- /dev/null +++ b/src/main/java/com/javarush/domain/exceptions/CityNotFound.java @@ -0,0 +1,7 @@ +package com.javarush.domain.exceptions; + +public class CityNotFound extends RuntimeException { + public CityNotFound(String message) { + super(message); + } +} diff --git a/src/main/java/com/javarush/domain/exceptions/CountryException.java b/src/main/java/com/javarush/domain/exceptions/CountryException.java new file mode 100644 index 0000000..98ee80d --- /dev/null +++ b/src/main/java/com/javarush/domain/exceptions/CountryException.java @@ -0,0 +1,7 @@ +package com.javarush.domain.exceptions; + +public class CountryException extends RuntimeException { + public CountryNotFound(String message) { + super(message); + } +} From 8276d0f90030cfbeaf907f1309e1025ea785bcb3 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Sat, 5 Oct 2024 19:30:15 +0200 Subject: [PATCH 28/48] refactor: name changed --- .../java/com/javarush/domain/exceptions/CityException.java | 7 +++++++ .../java/com/javarush/domain/exceptions/CityNotFound.java | 7 ------- .../com/javarush/domain/exceptions/CountryException.java | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/javarush/domain/exceptions/CityException.java delete mode 100644 src/main/java/com/javarush/domain/exceptions/CityNotFound.java diff --git a/src/main/java/com/javarush/domain/exceptions/CityException.java b/src/main/java/com/javarush/domain/exceptions/CityException.java new file mode 100644 index 0000000..b5efd0b --- /dev/null +++ b/src/main/java/com/javarush/domain/exceptions/CityException.java @@ -0,0 +1,7 @@ +package com.javarush.domain.exceptions; + +public class CityException extends RuntimeException { + public CityException(String message) { + super(message); + } +} diff --git a/src/main/java/com/javarush/domain/exceptions/CityNotFound.java b/src/main/java/com/javarush/domain/exceptions/CityNotFound.java deleted file mode 100644 index c979d13..0000000 --- a/src/main/java/com/javarush/domain/exceptions/CityNotFound.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.javarush.domain.exceptions; - -public class CityNotFound extends RuntimeException { - public CityNotFound(String message) { - super(message); - } -} diff --git a/src/main/java/com/javarush/domain/exceptions/CountryException.java b/src/main/java/com/javarush/domain/exceptions/CountryException.java index 98ee80d..6f278c1 100644 --- a/src/main/java/com/javarush/domain/exceptions/CountryException.java +++ b/src/main/java/com/javarush/domain/exceptions/CountryException.java @@ -1,7 +1,7 @@ package com.javarush.domain.exceptions; public class CountryException extends RuntimeException { - public CountryNotFound(String message) { + public CountryException(String message) { super(message); } } From ed752cb86391641ccea0ac2380246d8a14d43e58 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Sat, 5 Oct 2024 19:30:38 +0200 Subject: [PATCH 29/48] feat: add services --- .../com/javarush/services/CityService.java | 103 ++++++++++++------ .../com/javarush/services/CountryService.java | 85 +++++++++++++-- 2 files changed, 143 insertions(+), 45 deletions(-) diff --git a/src/main/java/com/javarush/services/CityService.java b/src/main/java/com/javarush/services/CityService.java index 489df3c..a751713 100644 --- a/src/main/java/com/javarush/services/CityService.java +++ b/src/main/java/com/javarush/services/CityService.java @@ -1,57 +1,92 @@ package com.javarush.services; import com.javarush.domain.entity.City; -import org.hibernate.SessionFactory; -import org.hibernate.query.Query; +import com.javarush.domain.exceptions.CityException; +import com.javarush.repository.CityRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; import java.util.List; public class CityService { - private final SessionFactory sessionFactory; - private final CountryService countryService; - private static final Logger LOGGER = LoggerFactory.getLogger(CountryService.class); + private static final Logger LOGGER = LoggerFactory.getLogger(CityService.class); - public CityService(SessionFactory sessionFactory, CountryService countryService) { - this.sessionFactory = sessionFactory; - this.countryService = countryService; + public City getById(Long id) { + try { + City city = new CityRepository().getById(id); + if (city == null) { + LOGGER.error("ERROR :: city with id {} not found", id); + throw new CityException("ERROR :: city with id " + id + " not found"); + } + return city; + }catch (Exception e){ + LOGGER.error("ERROR :: cannot get city with id {}", id); + throw new CityException("ERROR :: cannot get city with id " + id); + } } - public List getItems(int offset, int limit) { + public City save(City entity) { try { - System.out.println("HELLO from getItems"); - Query query = sessionFactory.getCurrentSession().createQuery("select c from City c", City.class); - query.setFirstResult(offset); - query.setMaxResults(limit); - return query.list(); - } catch (Exception e) { - LOGGER.error("Error fetching cities with offset {} and limit {}. Error message :: {}", offset, limit, e.getMessage()); - return new ArrayList<>(); + City city = new CityRepository().save(entity); + if (city == null) { + LOGGER.error("ERROR :: no city with id {}", entity.getId()); + throw new CityException("ERROR :: no city with id " + entity.getId()); + } + return city; + }catch(Exception e) { + LOGGER.error("ERROR :: cannot save city with id {}", entity.getId()); + throw new CityException("ERROR :: cannot save city with id " + entity.getId()); } } - public int getTotalCount() { - try { - System.out.println("HELLO from getTotal count"); - Query query = sessionFactory.getCurrentSession().createQuery("select count(c) from City c", Long.class); - return Math.toIntExact(query.uniqueResult()); - } catch (Exception e) { - LOGGER.error("Error fetching total city count. Error message :: {}", e.getMessage()); - return 0; + public void delete(Long id) { + try{ + new CityRepository().delete(id); + }catch (Exception e){ + LOGGER.error("ERROR :: cannot delete city with id: {}", id); + throw new CityException("ERROR :: cannot delete city with id: " + id); } } - public City getById(Integer id) { + public List getAll() { try { - System.out.println("HELLO from get by id"); - Query query = sessionFactory.getCurrentSession().createQuery("select c from City c join fetch c.countryId where c.id = :ID", City.class); - query.setParameter("ID", id); - return query.getSingleResult(); - } catch (Exception e) { - LOGGER.error("Error fetching city with ID {}. Error message :: {}", id, e.getMessage()); - return null; + List cities = new CityRepository().getAll(); + if (cities.isEmpty()) { + LOGGER.error("ERROR :: no cities found"); + throw new CityException("ERROR :: no cities found"); + } + return cities; + }catch (Exception e){ + LOGGER.error("ERROR :: cannot get all cities"); + throw new CityException("ERROR :: cannot get all cities"); + } + } + + public List getItems(int offset, int limit) { + try{ + List cities = new CityRepository().getItems(offset, limit); + if (cities.isEmpty()) { + LOGGER.error("ERROR :: no cities found in range"); + throw new CityException("ERROR :: no cities found in range"); + } + return cities; + }catch (Exception e){ + LOGGER.error("ERROR :: cannot get all cities in range"); + throw new CityException("ERROR :: cannot get all cities in range"); + } + } + + public int getTotalCount() { + try{ + int totalCount = new CityRepository().getTotalCount(); + if (totalCount == 0) { + LOGGER.error("ERROR :: total cities count is 0"); + throw new CityException("ERROR :: total cities count is 0"); + } + return totalCount; + }catch(Exception e){ + LOGGER.error("ERROR :: cannot get all cities count"); + throw new CityException("ERROR :: cannot get all cities count"); } } } diff --git a/src/main/java/com/javarush/services/CountryService.java b/src/main/java/com/javarush/services/CountryService.java index 16dfe02..f0823b0 100644 --- a/src/main/java/com/javarush/services/CountryService.java +++ b/src/main/java/com/javarush/services/CountryService.java @@ -1,29 +1,92 @@ package com.javarush.services; import com.javarush.domain.entity.Country; -import org.hibernate.SessionFactory; -import org.hibernate.query.Query; +import com.javarush.domain.exceptions.CountryException; +import com.javarush.repository.CountryRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Collections; import java.util.List; public class CountryService { - private final SessionFactory sessionFactory; private static final Logger LOGGER = LoggerFactory.getLogger(CountryService.class); - public CountryService(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; + public Country getById(Long id) { + try { + Country country = new CountryRepository().getById(id); + if (country == null) { + LOGGER.error("ERROR :: country with id {} not found", id); + throw new CountryException("ERROR :: country with id " + id + " not found"); + } + return country; + }catch (Exception e){ + LOGGER.error("ERROR :: cannot get country with id {}", id); + throw new CountryException("ERROR :: cannot get country with id " + id); + } + } + + public Country save(Country entity) { + try { + Country country = new CountryRepository().save(entity); + if (country == null) { + LOGGER.error("ERROR :: no country with id {}", entity.getId()); + throw new CountryException("ERROR :: no country with id " + entity.getId()); + } + return country; + }catch(Exception e) { + LOGGER.error("ERROR :: cannot save country with id {}", entity.getId()); + throw new CountryException("ERROR :: cannot save country with id " + entity.getId()); + } + } + + public void delete(Long id) { + try{ + new CountryRepository().delete(id); + }catch (Exception e){ + LOGGER.error("ERROR :: cannot delete country with id: {}", id); + throw new CountryException("ERROR :: cannot delete country with id: " + id); + } } public List getAll() { try { - Query query = sessionFactory.getCurrentSession().createQuery("select c from Country c join fetch c.languages", Country.class); - return query.list(); - } catch (Exception e) { - LOGGER.error("Error fetching countries", e); - return Collections.emptyList(); + List countries = new CountryRepository().getAll(); + if (countries.isEmpty()) { + LOGGER.error("ERROR :: no countries found"); + throw new CountryException("ERROR :: no countries found"); + } + return countries; + }catch (Exception e){ + LOGGER.error("ERROR :: cannot get all countries"); + throw new CountryException("ERROR :: cannot get all countries"); + } + } + + public List getItems(int offset, int limit) { + try{ + List countries = new CountryRepository().getItems(offset, limit); + if (countries.isEmpty()) { + LOGGER.error("ERROR :: no countries found in range"); + throw new CountryException("ERROR :: no countries found in range"); + } + return countries; + }catch (Exception e){ + LOGGER.error("ERROR :: cannot get all countries in range"); + throw new CountryException("ERROR :: cannot get all countries in range"); + } + } + + public int getTotalCount() { + try{ + int totalCount = new CountryRepository().getTotalCount(); + if (totalCount == 0) { + LOGGER.error("ERROR :: total countries count is 0"); + throw new CountryException("ERROR :: total countries count is 0"); + } + return totalCount; + }catch(Exception e){ + LOGGER.error("ERROR :: cannot get all countries count"); + throw new CountryException("ERROR :: cannot get all countries count"); } } } From dc7907adce740c27953f369aee6279e8836c4658 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Sat, 5 Oct 2024 19:31:04 +0200 Subject: [PATCH 30/48] refactor: add methods --- .../javarush/repository/CountryRepository.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/javarush/repository/CountryRepository.java b/src/main/java/com/javarush/repository/CountryRepository.java index 0db4bd2..5555a0d 100644 --- a/src/main/java/com/javarush/repository/CountryRepository.java +++ b/src/main/java/com/javarush/repository/CountryRepository.java @@ -49,11 +49,24 @@ public List getAll() { @Override public List getItems(int offset, int limit) { - return List.of(); + try(Session session = sessionFactory.getCurrentSession()) { + session.beginTransaction(); + List countryList = session.createQuery("select c from Country c", Country.class) + .setFirstResult(offset) + .setMaxResults(limit) + .list(); + session.getTransaction().commit(); + return countryList; + } } @Override public int getTotalCount() { - return 0; + try(Session session = sessionFactory.getCurrentSession()) { + session.beginTransaction(); + int intExact = Math.toIntExact(session.createQuery("select count(c) from Country c", Long.class).uniqueResult()); + session.getTransaction().commit(); + return intExact; + } } } From 61e06e0827839a08730e01db438b9d3cab6e3bd1 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Sat, 5 Oct 2024 22:16:20 +0200 Subject: [PATCH 31/48] refactor: change variable type --- src/main/java/com/javarush/domain/entity/Country.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/javarush/domain/entity/Country.java b/src/main/java/com/javarush/domain/entity/Country.java index 720dc62..7e2000d 100644 --- a/src/main/java/com/javarush/domain/entity/Country.java +++ b/src/main/java/com/javarush/domain/entity/Country.java @@ -32,7 +32,7 @@ public class Country { @Column(name = "surface_area") private BigDecimal surfaceArea; @Column(name = "indep_year") - private short indepYear; + private Short indepYear; @Column(name = "population") private int population; @Column(name = "life_expectancy") From 928b932ab7539120f3f5f19f5b576c1f7b2f4d3f Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Sat, 5 Oct 2024 22:17:04 +0200 Subject: [PATCH 32/48] fix: bug fixes --- .../com/javarush/repository/CountryRepository.java | 10 ++++++++-- .../java/com/javarush/services/CountryService.java | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/javarush/repository/CountryRepository.java b/src/main/java/com/javarush/repository/CountryRepository.java index 5555a0d..1eb6dc2 100644 --- a/src/main/java/com/javarush/repository/CountryRepository.java +++ b/src/main/java/com/javarush/repository/CountryRepository.java @@ -13,9 +13,12 @@ public class CountryRepository implements CrudRepository { @Override public Country getById(Long id) { try (Session session = sessionFactory.getCurrentSession()) { - return session.createQuery("select c from Country c join fetch c.languages where c.id = :ID", Country.class) + session.beginTransaction(); + Country country = session.createQuery("select c from Country c join fetch c.languages where c.id = :ID", Country.class) .setParameter("ID", id) .getSingleResult(); + session.getTransaction().commit(); + return country; } } @@ -43,7 +46,10 @@ public void delete(Long id) { @Override public List getAll() { try (Session session = sessionFactory.getCurrentSession()) { - return session.createQuery("select c from Country c join fetch c.languages", Country.class).list(); + session.beginTransaction(); + List list = session.createQuery("select c from Country c join fetch c.languages", Country.class).list(); + session.getTransaction().commit(); + return list; } } diff --git a/src/main/java/com/javarush/services/CountryService.java b/src/main/java/com/javarush/services/CountryService.java index f0823b0..da02879 100644 --- a/src/main/java/com/javarush/services/CountryService.java +++ b/src/main/java/com/javarush/services/CountryService.java @@ -58,7 +58,7 @@ public List getAll() { return countries; }catch (Exception e){ LOGGER.error("ERROR :: cannot get all countries"); - throw new CountryException("ERROR :: cannot get all countries"); + throw new CountryException("ERROR :: cannot get all countries: " + e); } } From 06b06ec2e2b6cb7291f1f370aa6954cbf1642a5e Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Sat, 5 Oct 2024 22:17:27 +0200 Subject: [PATCH 33/48] feat: add redis exception --- .../com/javarush/domain/exceptions/RedisException.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/com/javarush/domain/exceptions/RedisException.java diff --git a/src/main/java/com/javarush/domain/exceptions/RedisException.java b/src/main/java/com/javarush/domain/exceptions/RedisException.java new file mode 100644 index 0000000..41ace4d --- /dev/null +++ b/src/main/java/com/javarush/domain/exceptions/RedisException.java @@ -0,0 +1,7 @@ +package com.javarush.domain.exceptions; + +public class RedisException extends RuntimeException { + public RedisException(String message) { + super(message); + } +} From 1fccc38fcd1107202f3b86288ee9ff20c47e4096 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Sat, 5 Oct 2024 22:59:22 +0200 Subject: [PATCH 34/48] fix: bug fixes --- src/main/java/com/javarush/domain/entity/City.java | 2 +- src/main/java/com/javarush/domain/entity/Country.java | 2 +- .../java/com/javarush/domain/entity/CountryLanguage.java | 2 +- src/main/java/com/javarush/repository/CityRepository.java | 6 +++--- .../java/com/javarush/repository/CountryRepository.java | 6 +++--- src/main/java/com/javarush/services/CityService.java | 6 +++--- src/main/java/com/javarush/services/CountryService.java | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/javarush/domain/entity/City.java b/src/main/java/com/javarush/domain/entity/City.java index f1aef0c..377dbd5 100644 --- a/src/main/java/com/javarush/domain/entity/City.java +++ b/src/main/java/com/javarush/domain/entity/City.java @@ -13,7 +13,7 @@ public class City { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private int id; + private Integer id; @ManyToOne @JoinColumn(name = "country_id") private Country countryId; diff --git a/src/main/java/com/javarush/domain/entity/Country.java b/src/main/java/com/javarush/domain/entity/Country.java index 7e2000d..a0120da 100644 --- a/src/main/java/com/javarush/domain/entity/Country.java +++ b/src/main/java/com/javarush/domain/entity/Country.java @@ -17,7 +17,7 @@ public class Country { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private int id; + private Integer id; @Column(name = "code") private String code; @Column(name = "code_2") diff --git a/src/main/java/com/javarush/domain/entity/CountryLanguage.java b/src/main/java/com/javarush/domain/entity/CountryLanguage.java index b56aa35..9fc0514 100644 --- a/src/main/java/com/javarush/domain/entity/CountryLanguage.java +++ b/src/main/java/com/javarush/domain/entity/CountryLanguage.java @@ -16,7 +16,7 @@ public class CountryLanguage { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private int id; + private Integer id; @ManyToOne @JoinColumn(name = "country_id") private Country countryId; diff --git a/src/main/java/com/javarush/repository/CityRepository.java b/src/main/java/com/javarush/repository/CityRepository.java index 8a84950..cf44c08 100644 --- a/src/main/java/com/javarush/repository/CityRepository.java +++ b/src/main/java/com/javarush/repository/CityRepository.java @@ -7,11 +7,11 @@ import java.util.List; -public class CityRepository implements CrudRepository { +public class CityRepository implements CrudRepository { private final SessionFactory sessionFactory = HibernateUtil.prepareRelationalDb(); @Override - public City getById(Long id) { + public City getById(Integer id) { try (Session session = sessionFactory.getCurrentSession()) { session.beginTransaction(); City city = session.createQuery("select c from City c join fetch c.countryId where c.id = :ID", City.class) @@ -33,7 +33,7 @@ public City save(City entity) { } @Override - public void delete(Long id) { + public void delete(Integer id) { try (Session session = sessionFactory.getCurrentSession()) { session.beginTransaction(); session.createQuery("delete from City c where c.id = :ID", City.class) diff --git a/src/main/java/com/javarush/repository/CountryRepository.java b/src/main/java/com/javarush/repository/CountryRepository.java index 1eb6dc2..9422c42 100644 --- a/src/main/java/com/javarush/repository/CountryRepository.java +++ b/src/main/java/com/javarush/repository/CountryRepository.java @@ -7,11 +7,11 @@ import java.util.List; -public class CountryRepository implements CrudRepository { +public class CountryRepository implements CrudRepository { private final SessionFactory sessionFactory = HibernateUtil.prepareRelationalDb(); @Override - public Country getById(Long id) { + public Country getById(Integer id) { try (Session session = sessionFactory.getCurrentSession()) { session.beginTransaction(); Country country = session.createQuery("select c from Country c join fetch c.languages where c.id = :ID", Country.class) @@ -33,7 +33,7 @@ public Country save(Country entity) { } @Override - public void delete(Long id) { + public void delete(Integer id) { try (Session session = sessionFactory.getCurrentSession()) { session.beginTransaction(); session.createQuery("delete from Country c where c.id = :ID", Country.class) diff --git a/src/main/java/com/javarush/services/CityService.java b/src/main/java/com/javarush/services/CityService.java index a751713..3e119ad 100644 --- a/src/main/java/com/javarush/services/CityService.java +++ b/src/main/java/com/javarush/services/CityService.java @@ -11,7 +11,7 @@ public class CityService { private static final Logger LOGGER = LoggerFactory.getLogger(CityService.class); - public City getById(Long id) { + public City getById(Integer id) { try { City city = new CityRepository().getById(id); if (city == null) { @@ -21,7 +21,7 @@ public City getById(Long id) { return city; }catch (Exception e){ LOGGER.error("ERROR :: cannot get city with id {}", id); - throw new CityException("ERROR :: cannot get city with id " + id); + throw new CityException("ERROR :: cannot get city with id " + id + e); } } @@ -39,7 +39,7 @@ public City save(City entity) { } } - public void delete(Long id) { + public void delete(Integer id) { try{ new CityRepository().delete(id); }catch (Exception e){ diff --git a/src/main/java/com/javarush/services/CountryService.java b/src/main/java/com/javarush/services/CountryService.java index da02879..35de341 100644 --- a/src/main/java/com/javarush/services/CountryService.java +++ b/src/main/java/com/javarush/services/CountryService.java @@ -11,7 +11,7 @@ public class CountryService { private static final Logger LOGGER = LoggerFactory.getLogger(CountryService.class); - public Country getById(Long id) { + public Country getById(Integer id) { try { Country country = new CountryRepository().getById(id); if (country == null) { @@ -39,7 +39,7 @@ public Country save(Country entity) { } } - public void delete(Long id) { + public void delete(Integer id) { try{ new CountryRepository().delete(id); }catch (Exception e){ From 498cd0c4d4727599aaeef31efa6fe8926e9528ff Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Sun, 6 Oct 2024 11:31:19 +0200 Subject: [PATCH 35/48] feat: add redis logic for the most requested items --- .../com/javarush/cache/RedisRepository.java | 86 +++++++++++++++++++ .../cache/redis_enum/RedisModuleCommand.java | 25 ++++++ .../java/com/javarush/config/RedisConfig.java | 15 ++++ 3 files changed, 126 insertions(+) create mode 100644 src/main/java/com/javarush/cache/RedisRepository.java create mode 100644 src/main/java/com/javarush/cache/redis_enum/RedisModuleCommand.java create mode 100644 src/main/java/com/javarush/config/RedisConfig.java diff --git a/src/main/java/com/javarush/cache/RedisRepository.java b/src/main/java/com/javarush/cache/RedisRepository.java new file mode 100644 index 0000000..faf1f02 --- /dev/null +++ b/src/main/java/com/javarush/cache/RedisRepository.java @@ -0,0 +1,86 @@ +package com.javarush.cache; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.javarush.cache.redis_enum.RedisModuleCommand; +import redis.clients.jedis.Jedis; + +import java.util.ArrayList; +import java.util.List; + +public class RedisRepository { + private final Jedis jedis; + private final ObjectMapper objectMapper; + private static final String TOP_K_NAME = "topk_queries"; + + public RedisRepository() { + this.objectMapper = new ObjectMapper(); + this.jedis = new Jedis(); + jedis.sendCommand(RedisModuleCommand.RESERVE, TOP_K_NAME, "500"); + } + + public void save(String key, T entity) { + jedis.set(key, serialize(entity)); + } + + public T getById(String key, Class clazz) { //? + String serializedEntity = jedis.get(key); + if (serializedEntity != null) { + jedis.sendCommand(RedisModuleCommand.ADD, TOP_K_NAME, key); + return deserialize(serializedEntity, clazz); + } + return null; + } + + public void delete(String key) { + jedis.del(key); + } + + public List getAll(String listName, Class clazz) { + List str = jedis.lrange(listName, 0, -1); + List typeClass = new ArrayList<>(); + for (String s : str) { + typeClass.add(deserialize(s, clazz)); + } + return typeClass; + } + + public List getItems(String listName, int offset, int limit, Class clazz) { + List str = jedis.lrange(listName, offset, limit - 1); + List typeClass = new ArrayList<>(); + for (String s : str) { + typeClass.add(deserialize(s, clazz)); + } + return typeClass; + } + + public int getTotalCount(String listName) { + return Math.toIntExact(jedis.llen(listName)); + } + + public List getTopKQueries(int k) { + Object object = jedis.sendCommand(RedisModuleCommand.LIST, TOP_K_NAME, String.valueOf(k)); + if (object instanceof List) { + return (List) object; + } + System.out.println("cannot cast object to list"); + return null; + } + + private String serialize(T entity) { + try { + return objectMapper.writeValueAsString(entity); + } catch (Exception e) { + System.err.println("Error serializing object: " + e.getMessage()); + return null; + } + } + + private T deserialize(String serializedEntity, Class clazz) { + try { + return objectMapper.readValue(serializedEntity, clazz); + } catch (Exception e) { + System.err.println("Error deserializing object: " + e.getMessage()); + return null; + } + } +} diff --git a/src/main/java/com/javarush/cache/redis_enum/RedisModuleCommand.java b/src/main/java/com/javarush/cache/redis_enum/RedisModuleCommand.java new file mode 100644 index 0000000..ded5963 --- /dev/null +++ b/src/main/java/com/javarush/cache/redis_enum/RedisModuleCommand.java @@ -0,0 +1,25 @@ +package com.javarush.cache.redis_enum; + +import redis.clients.jedis.util.SafeEncoder; +import redis.clients.jedis.commands.ProtocolCommand; + +public enum RedisModuleCommand implements ProtocolCommand { + RESERVE("TOPK.RESERVE"), + ADD("TOPK.ADD"), + INCRBY("TOPK.INCRBY"), + QUERY("TOPK.QUERY"), + COUNT("TOPK.COUNT"), + LIST("TOPK.LIST"), + INFO("TOPK.INFO"); + + private final byte[] raw; + + RedisModuleCommand(String alt) { + raw = SafeEncoder.encode(alt); + } + + @Override + public byte[] getRaw() { + return raw; + } +} diff --git a/src/main/java/com/javarush/config/RedisConfig.java b/src/main/java/com/javarush/config/RedisConfig.java new file mode 100644 index 0000000..6e4468e --- /dev/null +++ b/src/main/java/com/javarush/config/RedisConfig.java @@ -0,0 +1,15 @@ +package com.javarush.config; + +import io.lettuce.core.RedisClient; +import io.lettuce.core.RedisURI; +import io.lettuce.core.api.StatefulRedisConnection; + +public class RedisConfig { + public static RedisClient prepareRedisClient() { + RedisClient redisClient = RedisClient.create(RedisURI.create("localhost", 6379)); + try (StatefulRedisConnection connection = redisClient.connect()) { + System.out.println("\nConnected to Redis\n"); + } + return redisClient; + } +} From 733093fcb6c1f4cb15b584c91d59968daa121fbc Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Sun, 6 Oct 2024 11:31:38 +0200 Subject: [PATCH 36/48] feat: add config class --- .../com/javarush/config/HibernateUtil.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/javarush/config/HibernateUtil.java b/src/main/java/com/javarush/config/HibernateUtil.java index 4907a7e..f0e46ee 100644 --- a/src/main/java/com/javarush/config/HibernateUtil.java +++ b/src/main/java/com/javarush/config/HibernateUtil.java @@ -13,7 +13,13 @@ import java.util.Properties; public class HibernateUtil { - public static SessionFactory prepareRelationalDb() { + private static SessionFactory sessionFactory; + + private HibernateUtil() { + + } + + private static SessionFactory prepareRelationalDb() { final SessionFactory sessionFactory; Properties properties = new Properties(); properties.put(Environment.DIALECT, "org.hibernate.dialect.MySQL8Dialect"); @@ -34,13 +40,10 @@ public static SessionFactory prepareRelationalDb() { return sessionFactory; } - public RedisClient prepareRedisClient() { - RedisClient redisClient = RedisClient.create(RedisURI.create("localhost", 6379)); - try (StatefulRedisConnection connection = redisClient.connect()) { - System.out.println("\nConnected to Redis\n"); + public static SessionFactory getSessionFactory() { + if(sessionFactory == null) { + sessionFactory = prepareRelationalDb(); } - return redisClient; + return sessionFactory; } - - } From d32696d1dfad60ea859822a72d185ed665baff52 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Sun, 6 Oct 2024 14:48:47 +0200 Subject: [PATCH 37/48] fix: bugs fixed --- .../com/javarush/cache/RedisRepository.java | 109 ++++++++++-------- 1 file changed, 59 insertions(+), 50 deletions(-) diff --git a/src/main/java/com/javarush/cache/RedisRepository.java b/src/main/java/com/javarush/cache/RedisRepository.java index faf1f02..446abe5 100644 --- a/src/main/java/com/javarush/cache/RedisRepository.java +++ b/src/main/java/com/javarush/cache/RedisRepository.java @@ -1,37 +1,74 @@ package com.javarush.cache; import com.fasterxml.jackson.databind.ObjectMapper; -import com.javarush.cache.redis_enum.RedisModuleCommand; -import redis.clients.jedis.Jedis; +import com.javarush.services.CityService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import redis.clients.jedis.UnifiedJedis; +import redis.clients.jedis.util.SafeEncoder; -import java.util.ArrayList; -import java.util.List; - -public class RedisRepository { - private final Jedis jedis; - private final ObjectMapper objectMapper; - private static final String TOP_K_NAME = "topk_queries"; +public class RedisRepository { + private final UnifiedJedis jedis; + private final ObjectMapper objectMapper = new ObjectMapper(); + private static final String TOPK_NAME = "city-country"; + private static final int THRESHOLD = 7; + private static final Logger LOGGER = LoggerFactory.getLogger(CityService.class); public RedisRepository() { - this.objectMapper = new ObjectMapper(); - this.jedis = new Jedis(); - jedis.sendCommand(RedisModuleCommand.RESERVE, TOP_K_NAME, "500"); - } + jedis = new UnifiedJedis("redis://127.0.0.1:6379"); - public void save(String key, T entity) { - jedis.set(key, serialize(entity)); + jedis.del(TOPK_NAME); + if (!jedis.exists(TOPK_NAME)) { + jedis.topkReserve(TOPK_NAME, 5L, 2000L, 7L, 0.925D); + } } - public T getById(String key, Class clazz) { //? + public T getById(String key, Class clazz) { String serializedEntity = jedis.get(key); - if (serializedEntity != null) { - jedis.sendCommand(RedisModuleCommand.ADD, TOP_K_NAME, key); - return deserialize(serializedEntity, clazz); + return deserialize(serializedEntity, clazz); + } + + public void put(String key, T value) { + jedis.topkAdd(TOPK_NAME, key); + + if (getCount(key) >= THRESHOLD) { + System.out.println(serialize(value)); + jedis.set(key, serialize(value)); } - return null; } - public void delete(String key) { + private int getCount(String key) { + String count = jedis.sendCommand(() -> SafeEncoder.encode("TOPK.COUNT"), SafeEncoder.encodeMany(TOPK_NAME, key)).toString(); + return Integer.parseInt(count.replaceAll("[\\[\\]]", "")); + } + + public boolean checkExists(String key) { + return jedis.exists(key); + } + + private String serialize(T entity) { + try { + return objectMapper.writeValueAsString(entity); + } catch (Exception e) { + LOGGER.error("Error serializing object: " + e.getMessage()); + return null; + } + } + + private T deserialize(String serializedEntity, Class clazz) { + try { + return objectMapper.readValue(serializedEntity, clazz); + } catch (Exception e) { + LOGGER.error("Error deserializing object: " + e.getMessage()); + return null; + } + } +} + +/*public void save(String key, T entity) { + jedis.set(key, serialize(entity)); + +public void delete(String key) { jedis.del(key); } @@ -55,32 +92,4 @@ public List getItems(String listName, int offset, int limit, Class clazz) public int getTotalCount(String listName) { return Math.toIntExact(jedis.llen(listName)); - } - - public List getTopKQueries(int k) { - Object object = jedis.sendCommand(RedisModuleCommand.LIST, TOP_K_NAME, String.valueOf(k)); - if (object instanceof List) { - return (List) object; - } - System.out.println("cannot cast object to list"); - return null; - } - - private String serialize(T entity) { - try { - return objectMapper.writeValueAsString(entity); - } catch (Exception e) { - System.err.println("Error serializing object: " + e.getMessage()); - return null; - } - } - - private T deserialize(String serializedEntity, Class clazz) { - try { - return objectMapper.readValue(serializedEntity, clazz); - } catch (Exception e) { - System.err.println("Error deserializing object: " + e.getMessage()); - return null; - } - } -} + }*/ From 820bc977a176ba0bdb14e138897544c0485b12da Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Sun, 6 Oct 2024 15:46:04 +0200 Subject: [PATCH 38/48] fix: bugs fixed --- .../com/javarush/cache/RedisRepository.java | 1 - .../cache/redis_enum/RedisModuleCommand.java | 25 ------ .../java/com/javarush/domain/entity/City.java | 2 +- .../com/javarush/domain/entity/Country.java | 2 +- .../javarush/repository/CityRepository.java | 35 +++----- .../repository/CountryRepository.java | 20 ++--- .../com/javarush/services/CityService.java | 66 ++++++++------- .../com/javarush/services/CountryService.java | 80 ++++++++++--------- .../CityCountryTransformerServiceTest.java | 69 ---------------- 9 files changed, 102 insertions(+), 198 deletions(-) delete mode 100644 src/main/java/com/javarush/cache/redis_enum/RedisModuleCommand.java delete mode 100644 src/test/java/com/javarush/CityCountryTransformerServiceTest.java diff --git a/src/main/java/com/javarush/cache/RedisRepository.java b/src/main/java/com/javarush/cache/RedisRepository.java index 446abe5..f16b382 100644 --- a/src/main/java/com/javarush/cache/RedisRepository.java +++ b/src/main/java/com/javarush/cache/RedisRepository.java @@ -32,7 +32,6 @@ public void put(String key, T value) { jedis.topkAdd(TOPK_NAME, key); if (getCount(key) >= THRESHOLD) { - System.out.println(serialize(value)); jedis.set(key, serialize(value)); } } diff --git a/src/main/java/com/javarush/cache/redis_enum/RedisModuleCommand.java b/src/main/java/com/javarush/cache/redis_enum/RedisModuleCommand.java deleted file mode 100644 index ded5963..0000000 --- a/src/main/java/com/javarush/cache/redis_enum/RedisModuleCommand.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.javarush.cache.redis_enum; - -import redis.clients.jedis.util.SafeEncoder; -import redis.clients.jedis.commands.ProtocolCommand; - -public enum RedisModuleCommand implements ProtocolCommand { - RESERVE("TOPK.RESERVE"), - ADD("TOPK.ADD"), - INCRBY("TOPK.INCRBY"), - QUERY("TOPK.QUERY"), - COUNT("TOPK.COUNT"), - LIST("TOPK.LIST"), - INFO("TOPK.INFO"); - - private final byte[] raw; - - RedisModuleCommand(String alt) { - raw = SafeEncoder.encode(alt); - } - - @Override - public byte[] getRaw() { - return raw; - } -} diff --git a/src/main/java/com/javarush/domain/entity/City.java b/src/main/java/com/javarush/domain/entity/City.java index 377dbd5..0a7f00f 100644 --- a/src/main/java/com/javarush/domain/entity/City.java +++ b/src/main/java/com/javarush/domain/entity/City.java @@ -22,5 +22,5 @@ public class City { @Column(name = "district") private String district; @Column(name = "population") - private int population; + private Integer population; } diff --git a/src/main/java/com/javarush/domain/entity/Country.java b/src/main/java/com/javarush/domain/entity/Country.java index a0120da..9f5eedc 100644 --- a/src/main/java/com/javarush/domain/entity/Country.java +++ b/src/main/java/com/javarush/domain/entity/Country.java @@ -34,7 +34,7 @@ public class Country { @Column(name = "indep_year") private Short indepYear; @Column(name = "population") - private int population; + private Integer population; @Column(name = "life_expectancy") private BigDecimal lifeExpectancy; @Column(name = "gnp") diff --git a/src/main/java/com/javarush/repository/CityRepository.java b/src/main/java/com/javarush/repository/CityRepository.java index cf44c08..dc6e275 100644 --- a/src/main/java/com/javarush/repository/CityRepository.java +++ b/src/main/java/com/javarush/repository/CityRepository.java @@ -4,37 +4,35 @@ import com.javarush.domain.entity.City; import org.hibernate.Session; import org.hibernate.SessionFactory; +import org.hibernate.Transaction; import java.util.List; public class CityRepository implements CrudRepository { - private final SessionFactory sessionFactory = HibernateUtil.prepareRelationalDb(); + private final SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); @Override public City getById(Integer id) { - try (Session session = sessionFactory.getCurrentSession()) { - session.beginTransaction(); - City city = session.createQuery("select c from City c join fetch c.countryId where c.id = :ID", City.class) + try (Session session = sessionFactory.openSession()) { + return session.createQuery("select c from City c join fetch c.countryId where c.id = :ID", City.class) .setParameter("ID", id) .uniqueResult(); - session.getTransaction().commit(); - return city; } } @Override public City save(City entity) { - try (Session session = sessionFactory.getCurrentSession()) { - session.beginTransaction(); + try (Session session = sessionFactory.openSession()) { + Transaction transaction = session.beginTransaction(); session.persist(entity); - session.getTransaction().commit(); + transaction.commit(); return entity; } } @Override public void delete(Integer id) { - try (Session session = sessionFactory.getCurrentSession()) { + try (Session session = sessionFactory.openSession()) { session.beginTransaction(); session.createQuery("delete from City c where c.id = :ID", City.class) .setParameter("ID", id) @@ -46,33 +44,24 @@ public void delete(Integer id) { @Override public List getAll() { try (Session session = sessionFactory.getCurrentSession()) { - session.beginTransaction(); - List cityList = session.createQuery("select c from City c", City.class).list(); - session.getTransaction().commit(); - return cityList; + return session.createQuery("select c from City c", City.class).list(); } } @Override public List getItems(int offset, int limit) { try(Session session = sessionFactory.getCurrentSession()) { - session.beginTransaction(); - List cityList = session.createQuery("select c from City c", City.class) + return session.createQuery("select c from City c", City.class) .setFirstResult(offset) .setMaxResults(limit) .list(); - session.getTransaction().commit(); - return cityList; } } @Override public int getTotalCount() { - try(Session session = sessionFactory.getCurrentSession()) { - session.beginTransaction(); - int intExact = Math.toIntExact(session.createQuery("select count(c) from City c", Long.class).uniqueResult()); - session.getTransaction().commit(); - return intExact; + try(Session session = sessionFactory.openSession()) { + return Math.toIntExact(session.createQuery("select count(c) from City c", Long.class).uniqueResult()); } } } diff --git a/src/main/java/com/javarush/repository/CountryRepository.java b/src/main/java/com/javarush/repository/CountryRepository.java index 9422c42..64ec52e 100644 --- a/src/main/java/com/javarush/repository/CountryRepository.java +++ b/src/main/java/com/javarush/repository/CountryRepository.java @@ -8,17 +8,14 @@ import java.util.List; public class CountryRepository implements CrudRepository { - private final SessionFactory sessionFactory = HibernateUtil.prepareRelationalDb(); + private final SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); @Override public Country getById(Integer id) { - try (Session session = sessionFactory.getCurrentSession()) { - session.beginTransaction(); - Country country = session.createQuery("select c from Country c join fetch c.languages where c.id = :ID", Country.class) + try (Session session = sessionFactory.openSession()) { + return session.createQuery("select c from Country c where c.id = :ID", Country.class) .setParameter("ID", id) .getSingleResult(); - session.getTransaction().commit(); - return country; } } @@ -45,17 +42,14 @@ public void delete(Integer id) { @Override public List getAll() { - try (Session session = sessionFactory.getCurrentSession()) { - session.beginTransaction(); - List list = session.createQuery("select c from Country c join fetch c.languages", Country.class).list(); - session.getTransaction().commit(); - return list; + try (Session session = sessionFactory.openSession()) { + return session.createQuery("select c from Country c join fetch c.languages", Country.class).list(); } } @Override public List getItems(int offset, int limit) { - try(Session session = sessionFactory.getCurrentSession()) { + try (Session session = sessionFactory.getCurrentSession()) { session.beginTransaction(); List countryList = session.createQuery("select c from Country c", Country.class) .setFirstResult(offset) @@ -68,7 +62,7 @@ public List getItems(int offset, int limit) { @Override public int getTotalCount() { - try(Session session = sessionFactory.getCurrentSession()) { + try (Session session = sessionFactory.getCurrentSession()) { session.beginTransaction(); int intExact = Math.toIntExact(session.createQuery("select count(c) from Country c", Long.class).uniqueResult()); session.getTransaction().commit(); diff --git a/src/main/java/com/javarush/services/CityService.java b/src/main/java/com/javarush/services/CityService.java index 3e119ad..126cdee 100644 --- a/src/main/java/com/javarush/services/CityService.java +++ b/src/main/java/com/javarush/services/CityService.java @@ -1,7 +1,10 @@ package com.javarush.services; +import com.javarush.DataTransformer; +import com.javarush.cache.RedisRepository; import com.javarush.domain.entity.City; import com.javarush.domain.exceptions.CityException; +import com.javarush.redis.CityCountry; import com.javarush.repository.CityRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -10,18 +13,23 @@ public class CityService { private static final Logger LOGGER = LoggerFactory.getLogger(CityService.class); + private final RedisRepository redisRepository = new RedisRepository(); + private final CityRepository cityRepository = new CityRepository(); + private final DataTransformer dataTransformer = new DataTransformer(); public City getById(Integer id) { + String key = "city_" + id; try { - City city = new CityRepository().getById(id); - if (city == null) { - LOGGER.error("ERROR :: city with id {} not found", id); - throw new CityException("ERROR :: city with id " + id + " not found"); + if(redisRepository.checkExists(key)){ + CityCountry cityCountry = redisRepository.getById(key, CityCountry.class); + return dataTransformer.cityCountryTransformToCity(cityCountry); } + City city = cityRepository.getById(id); + redisRepository.put(key, dataTransformer.cityTransformToCityCountry(city)); return city; - }catch (Exception e){ - LOGGER.error("ERROR :: cannot get city with id {}", id); - throw new CityException("ERROR :: cannot get city with id " + id + e); + } catch (Exception e) { + LOGGER.error("Cannot get city with id {}", id); + throw new CityException("ERROR :: cannot get city with id " + id + " " + e.getMessage()); } } @@ -29,22 +37,22 @@ public City save(City entity) { try { City city = new CityRepository().save(entity); if (city == null) { - LOGGER.error("ERROR :: no city with id {}", entity.getId()); + LOGGER.error("No city with id {}", entity.getId()); throw new CityException("ERROR :: no city with id " + entity.getId()); } return city; - }catch(Exception e) { - LOGGER.error("ERROR :: cannot save city with id {}", entity.getId()); - throw new CityException("ERROR :: cannot save city with id " + entity.getId()); + } catch (Exception e) { + LOGGER.error("Cannot save city with id {}", entity.getId()); + throw new CityException("ERROR :: cannot save city with id " + entity.getId() + " " + e.getMessage()); } } public void delete(Integer id) { - try{ + try { new CityRepository().delete(id); - }catch (Exception e){ - LOGGER.error("ERROR :: cannot delete city with id: {}", id); - throw new CityException("ERROR :: cannot delete city with id: " + id); + } catch (Exception e) { + LOGGER.error("Cannot delete city with id: {}", id); + throw new CityException("ERROR :: cannot delete city with id: " + id + " " + e.getMessage()); } } @@ -52,41 +60,41 @@ public List getAll() { try { List cities = new CityRepository().getAll(); if (cities.isEmpty()) { - LOGGER.error("ERROR :: no cities found"); + LOGGER.error("No cities found"); throw new CityException("ERROR :: no cities found"); } return cities; - }catch (Exception e){ - LOGGER.error("ERROR :: cannot get all cities"); - throw new CityException("ERROR :: cannot get all cities"); + } catch (Exception e) { + LOGGER.error("Cannot get all cities"); + throw new CityException("ERROR :: cannot get all cities: " + e.getMessage()); } } public List getItems(int offset, int limit) { - try{ + try { List cities = new CityRepository().getItems(offset, limit); if (cities.isEmpty()) { - LOGGER.error("ERROR :: no cities found in range"); + LOGGER.error("No cities found in range"); throw new CityException("ERROR :: no cities found in range"); } return cities; - }catch (Exception e){ - LOGGER.error("ERROR :: cannot get all cities in range"); - throw new CityException("ERROR :: cannot get all cities in range"); + } catch (Exception e) { + LOGGER.error("Cannot get all cities in range"); + throw new CityException("ERROR :: cannot get all cities in range: " + e.getMessage()); } } public int getTotalCount() { - try{ + try { int totalCount = new CityRepository().getTotalCount(); if (totalCount == 0) { - LOGGER.error("ERROR :: total cities count is 0"); + LOGGER.error("Total cities count is 0"); throw new CityException("ERROR :: total cities count is 0"); } return totalCount; - }catch(Exception e){ - LOGGER.error("ERROR :: cannot get all cities count"); - throw new CityException("ERROR :: cannot get all cities count"); + } catch (Exception e) { + LOGGER.error("Cannot get all cities count"); + throw new CityException("ERROR :: cannot get all cities count: " + e.getMessage()); } } } diff --git a/src/main/java/com/javarush/services/CountryService.java b/src/main/java/com/javarush/services/CountryService.java index 35de341..60867ec 100644 --- a/src/main/java/com/javarush/services/CountryService.java +++ b/src/main/java/com/javarush/services/CountryService.java @@ -1,7 +1,10 @@ package com.javarush.services; +import com.javarush.DataTransformer; +import com.javarush.cache.RedisRepository; import com.javarush.domain.entity.Country; import com.javarush.domain.exceptions.CountryException; +import com.javarush.redis.CityCountry; import com.javarush.repository.CountryRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -10,83 +13,88 @@ public class CountryService { private static final Logger LOGGER = LoggerFactory.getLogger(CountryService.class); + private final RedisRepository redisRepository = new RedisRepository(); + private final CountryRepository countryRepository = new CountryRepository(); + private final DataTransformer dataTransformer = new DataTransformer(); public Country getById(Integer id) { + String key = "country_" + id; try { - Country country = new CountryRepository().getById(id); - if (country == null) { - LOGGER.error("ERROR :: country with id {} not found", id); - throw new CountryException("ERROR :: country with id " + id + " not found"); + if (redisRepository.checkExists(key)) { + CityCountry cityCountry = redisRepository.getById(key, CityCountry.class); + return dataTransformer.cityCountryToCountry(cityCountry); } + Country country = countryRepository.getById(id); + redisRepository.put(key, dataTransformer.countryTransformToCityCountry(country)); return country; - }catch (Exception e){ - LOGGER.error("ERROR :: cannot get country with id {}", id); - throw new CountryException("ERROR :: cannot get country with id " + id); + } catch (Exception e) { + LOGGER.error("Cannot get country with id {}", id); + throw new CountryException("ERROR :: cannot get country with id " + id + " " + e.getMessage()); } } public Country save(Country entity) { try { - Country country = new CountryRepository().save(entity); - if (country == null) { - LOGGER.error("ERROR :: no country with id {}", entity.getId()); + Country savedCountry = countryRepository.save(entity); + if (savedCountry == null) { + LOGGER.error("Failed to save country with id {}", entity.getId()); throw new CountryException("ERROR :: no country with id " + entity.getId()); } - return country; - }catch(Exception e) { - LOGGER.error("ERROR :: cannot save country with id {}", entity.getId()); - throw new CountryException("ERROR :: cannot save country with id " + entity.getId()); + return savedCountry; + } catch (Exception ex) { + LOGGER.error("Could not save country with id {}", entity.getId(), ex); + throw new CountryException("ERROR :: could not save country with id " + entity.getId() + " " + ex.getMessage()); } } public void delete(Integer id) { - try{ - new CountryRepository().delete(id); - }catch (Exception e){ - LOGGER.error("ERROR :: cannot delete country with id: {}", id); - throw new CountryException("ERROR :: cannot delete country with id: " + id); + try { + countryRepository.delete(id); + } catch (Exception e) { + LOGGER.error("Cannot delete country with id: {}", id); + throw new CountryException("ERROR :: cannot delete country with id: " + id + " " + e.getMessage()); } } public List getAll() { try { - List countries = new CountryRepository().getAll(); + List countries = countryRepository.getAll(); if (countries.isEmpty()) { - LOGGER.error("ERROR :: no countries found"); + LOGGER.error("No countries found"); throw new CountryException("ERROR :: no countries found"); } return countries; - }catch (Exception e){ - LOGGER.error("ERROR :: cannot get all countries"); - throw new CountryException("ERROR :: cannot get all countries: " + e); + } catch (Exception e) { + LOGGER.error("Cannot get all countries"); + throw new CountryException("ERROR :: cannot get all countries: " + e.getMessage()); } } public List getItems(int offset, int limit) { - try{ - List countries = new CountryRepository().getItems(offset, limit); + try { + List countries = countryRepository.getItems(offset, limit); if (countries.isEmpty()) { - LOGGER.error("ERROR :: no countries found in range"); + LOGGER.error("No countries found in range"); throw new CountryException("ERROR :: no countries found in range"); } return countries; - }catch (Exception e){ - LOGGER.error("ERROR :: cannot get all countries in range"); - throw new CountryException("ERROR :: cannot get all countries in range"); + } catch (Exception e) { + LOGGER.error("Cannot get all countries in range"); + throw new CountryException("ERROR :: cannot get all countries in range: " + e.getMessage()); } } public int getTotalCount() { - try{ - int totalCount = new CountryRepository().getTotalCount(); + try { + int totalCount = countryRepository.getTotalCount(); if (totalCount == 0) { - LOGGER.error("ERROR :: total countries count is 0"); + LOGGER.error("Total countries count is 0"); throw new CountryException("ERROR :: total countries count is 0"); } return totalCount; - }catch(Exception e){ - LOGGER.error("ERROR :: cannot get all countries count"); - throw new CountryException("ERROR :: cannot get all countries count"); + } catch (Exception e) { + LOGGER.error("Cannot get all countries count"); + throw new CountryException("ERROR :: cannot get all countries count: " + e.getMessage()); } } } diff --git a/src/test/java/com/javarush/CityCountryTransformerServiceTest.java b/src/test/java/com/javarush/CityCountryTransformerServiceTest.java deleted file mode 100644 index f0914c4..0000000 --- a/src/test/java/com/javarush/CityCountryTransformerServiceTest.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.javarush; - -import com.javarush.domain.entity.City; -import com.javarush.domain.enums.Continent; -import com.javarush.domain.entity.Country; -import com.javarush.domain.entity.CountryLanguage; -import com.javarush.redis.CityCountry; -import com.javarush.redis.Language; -import com.javarush.services.CityCountryTransformerService; -import org.junit.jupiter.api.Test; - -import java.math.BigDecimal; -import java.util.List; -import java.util.Set; - -import static org.junit.jupiter.api.Assertions.*; - -class CityCountryTransformerServiceTest { - @Test - public void testInitialisation() { - City city = new City(); - city.setId(1); - city.setName("Test City"); - city.setPopulation(100000); - city.setDistrict("Test District"); - - Country country = new Country(); - country.setCode("TC"); - country.setCode2("TCC"); - country.setContinent(Continent.ASIA); - country.setName("Test Country"); - country.setPopulation(5000000); - country.setRegion("Test Region"); - country.setSurfaceArea(new BigDecimal("12345.67")); - - CountryLanguage countryLanguage = new CountryLanguage(); - countryLanguage.setLanguage("Test Language"); - countryLanguage.setIsOfficial(true); - countryLanguage.setPercentage(new BigDecimal("99.9")); - - city.setCountryId(country); - country.setLanguages(Set.of(countryLanguage)); - - CityCountryTransformerService cityCountryService = new CityCountryTransformerService(); - List result = cityCountryService.initialisation(List.of(city)); - - assertNotNull(result); - assertEquals(1, result.size()); - CityCountry cityCountry = result.get(0); - assertEquals(1, cityCountry.getId()); - assertEquals("Test City", cityCountry.getName()); - assertEquals(100000, cityCountry.getPopulation()); - assertEquals("Test District", cityCountry.getDistrict()); - assertEquals("TCC", cityCountry.getAlternativeCountryCode()); - assertEquals(Continent.ASIA, cityCountry.getContinent()); - assertEquals("TC", cityCountry.getCountryCode()); - assertEquals("Test Country", cityCountry.getCountryName()); - assertEquals(5000000, cityCountry.getCountryPopulation()); - assertEquals("Test Region", cityCountry.getCountryRegion()); - assertEquals(new BigDecimal("12345.67"), cityCountry.getCountrySurfaceArea()); - assertNotNull(cityCountry.getLanguages()); - assertEquals(1, cityCountry.getLanguages().size()); - Language language = cityCountry.getLanguages().iterator().next(); - assertEquals("Test Language", language.getLanguage()); - assertTrue(language.getIsOfficial()); - assertEquals(new BigDecimal("99.9"), language.getPercentage()); - } - -} \ No newline at end of file From 0bb5776d090132766aaca29cdf2e971b4a6b192c Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Sun, 6 Oct 2024 15:47:53 +0200 Subject: [PATCH 39/48] feat: add class for data transforming --- .../java/com/javarush/DataTransformer.java | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/main/java/com/javarush/DataTransformer.java diff --git a/src/main/java/com/javarush/DataTransformer.java b/src/main/java/com/javarush/DataTransformer.java new file mode 100644 index 0000000..797a502 --- /dev/null +++ b/src/main/java/com/javarush/DataTransformer.java @@ -0,0 +1,72 @@ +package com.javarush; + +import com.javarush.domain.entity.City; +import com.javarush.domain.entity.Country; +import com.javarush.domain.entity.CountryLanguage; +import com.javarush.redis.CityCountry; +import com.javarush.redis.Language; + +import java.util.Set; +import java.util.stream.Collectors; + +public class DataTransformer { + public CityCountry countryTransformToCityCountry(Country country) { + CityCountry res = new CityCountry(); + res.setAlternativeCountryCode(country.getCode2()); + res.setContinent(country.getContinent()); + res.setCountryCode(country.getCode()); + res.setCountryName(country.getName()); + res.setCountryPopulation(country.getPopulation()); + res.setCountryRegion(country.getRegion()); + res.setCountrySurfaceArea(country.getSurfaceArea()); + Set countryLanguages = country.getLanguages(); + Set languages = countryLanguages.stream().map(cl -> { + Language language = new Language(); + language.setLanguage(cl.getLanguage()); + language.setIsOfficial(cl.getIsOfficial()); + language.setPercentage(cl.getPercentage()); + return language; + }).collect(Collectors.toSet()); + res.setLanguages(languages); + return res; + } + + public CityCountry cityTransformToCityCountry(City city) { + CityCountry res = new CityCountry(); + res.setId(city.getId()); + res.setName(city.getName()); + res.setPopulation(city.getPopulation()); + res.setDistrict(city.getDistrict()); + return res; + } + + public City cityCountryTransformToCity(CityCountry cityCountry) { + City city = new City(); + city.setId(cityCountry.getId()); + city.setName(cityCountry.getName()); + city.setPopulation(cityCountry.getPopulation()); + city.setDistrict(cityCountry.getDistrict()); + return city; + } + + public Country cityCountryToCountry(CityCountry cityCountry) { + Country country = new Country(); + country.setCode2(cityCountry.getAlternativeCountryCode()); + country.setContinent(cityCountry.getContinent()); + country.setCode(cityCountry.getCountryCode()); + country.setName(cityCountry.getCountryName()); + country.setPopulation(cityCountry.getCountryPopulation()); + country.setRegion(cityCountry.getCountryRegion()); + country.setSurfaceArea(cityCountry.getCountrySurfaceArea()); + Set languages = cityCountry.getLanguages(); + Set countryLanguages = languages.stream().map(cl -> { + CountryLanguage countryLanguage = new CountryLanguage(); + countryLanguage.setLanguage(cl.getLanguage()); + countryLanguage.setIsOfficial(cl.getIsOfficial()); + countryLanguage.setPercentage(cl.getPercentage()); + return countryLanguage; + }).collect(Collectors.toSet()); + country.setLanguages(countryLanguages); + return country; + } +} From f49de321c73fbeb1f3d7cf72e69027ac8bb29c82 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Sun, 6 Oct 2024 15:48:10 +0200 Subject: [PATCH 40/48] style: delete unused imports --- src/main/java/com/javarush/config/HibernateUtil.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/com/javarush/config/HibernateUtil.java b/src/main/java/com/javarush/config/HibernateUtil.java index f0e46ee..ed23ee1 100644 --- a/src/main/java/com/javarush/config/HibernateUtil.java +++ b/src/main/java/com/javarush/config/HibernateUtil.java @@ -3,9 +3,6 @@ import com.javarush.domain.entity.City; import com.javarush.domain.entity.Country; import com.javarush.domain.entity.CountryLanguage; -import io.lettuce.core.RedisClient; -import io.lettuce.core.RedisURI; -import io.lettuce.core.api.StatefulRedisConnection; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; @@ -41,7 +38,7 @@ private static SessionFactory prepareRelationalDb() { } public static SessionFactory getSessionFactory() { - if(sessionFactory == null) { + if (sessionFactory == null) { sessionFactory = prepareRelationalDb(); } return sessionFactory; From db4c0cbf76356951f09fb7b154c363678f1ab33b Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Sun, 6 Oct 2024 15:48:25 +0200 Subject: [PATCH 41/48] fix: bugs fixed --- pom.xml | 92 ++++++++++++++++++++++ src/main/java/com/javarush/Main.java | 109 +++++++++++++++++++-------- 2 files changed, 171 insertions(+), 30 deletions(-) create mode 100644 pom.xml diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..5e52653 --- /dev/null +++ b/pom.xml @@ -0,0 +1,92 @@ + + 4.0.0 + + com.example + my-project + 1.0-SNAPSHOT + + + 8 + 8 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 20 + 20 + + + + + + + + mysql + mysql-connector-java + 8.0.30 + + + + org.hibernate + hibernate-core-jakarta + 5.6.14.Final + + + + p6spy + p6spy + 3.9.1 + + + + io.lettuce + lettuce-core + 6.2.2.RELEASE + + + + org.projectlombok + lombok + 1.18.30 + provided + + + + org.mockito + mockito-core + 5.12.0 + test + + + + org.mockito + mockito-junit-jupiter + 5.12.0 + test + + + + org.slf4j + slf4j-api + 2.0.13 + + + + com.fasterxml.jackson.core + jackson-databind + 2.14.0 + + + redis.clients + jedis + 5.2.0 + + + diff --git a/src/main/java/com/javarush/Main.java b/src/main/java/com/javarush/Main.java index 21fe43d..338b4b0 100644 --- a/src/main/java/com/javarush/Main.java +++ b/src/main/java/com/javarush/Main.java @@ -1,30 +1,40 @@ package com.javarush; -import com.javarush.config.DatabaseConfig; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.javarush.cache.RedisRepository; +import com.javarush.config.HibernateUtil; import com.javarush.config.RedisConfig; -import com.javarush.domain.City; +import com.javarush.domain.entity.City; +import com.javarush.domain.entity.CountryLanguage; import com.javarush.redis.CityCountry; -import com.javarush.services.CityCountryTransformerService; import com.javarush.services.CityService; import com.javarush.services.CountryService; -import com.javarush.services.RedisService; -import com.javarush.utils.CityDataProcessing; import io.lettuce.core.RedisClient; +import io.lettuce.core.api.StatefulRedisConnection; +import io.lettuce.core.api.sync.RedisStringCommands; +import org.hibernate.Session; import org.hibernate.SessionFactory; +import java.util.ArrayList; import java.util.List; +import java.util.Set; import static java.util.Objects.nonNull; public class Main { private final SessionFactory sessionFactory; private final RedisClient redisClient; + private final CityService cityService; + private final CountryService countryService; + private final ObjectMapper mapper; public Main() { - DatabaseConfig databaseConfig = new DatabaseConfig(); - sessionFactory = databaseConfig.prepareRelationalDb(); - RedisConfig redisConfig = new RedisConfig(); - redisClient = redisConfig.prepareRedisClient(); + sessionFactory = HibernateUtil.getSessionFactory(); + redisClient = RedisConfig.prepareRedisClient(); + cityService = new CityService(); + countryService = new CountryService(); + mapper = new ObjectMapper(); } private void shutdown() { @@ -37,33 +47,72 @@ private void shutdown() { } public static void main(String[] args) { - Main main = new Main(); - RedisService redisService = new RedisService(main.redisClient); + RedisRepository countryRedisRepository = new RedisRepository(); + RedisRepository cityRedisRepository = new RedisRepository(); - CountryService countryService = new CountryService(main.sessionFactory); - CityService cityService = new CityService(main.sessionFactory, countryService); - CityCountryTransformerService transformer = new CityCountryTransformerService(); - CityDataProcessing cityDataProcessing = new CityDataProcessing(main.sessionFactory, cityService, countryService); + CountryService countryService = new CountryService(); + CityService cityService = new CityService(); - List allCities = cityDataProcessing.fetchData(); - List preparedData = transformer.transformData(allCities); - redisService.pushToRedis(preparedData); - main.sessionFactory.getCurrentSession().close(); - - List ids = List.of(3, 2545, 123, 4, 189, 89, 3458, 1189, 10, 102); + System.out.println("Querying Country by ID..."); + for (int i = 0; i < 15; i++) { + countryService.getById(1); + cityService.getById(2); + } + } - long startRedis = System.currentTimeMillis(); - redisService.testRedisData(ids); - long stopRedis = System.currentTimeMillis(); + private void pushToRedis(List data) { + try (StatefulRedisConnection connection = redisClient.connect()) { + RedisStringCommands sync = connection.sync(); + for (CityCountry cityCountry : data) { + try { + sync.set(String.valueOf(cityCountry.getId()), mapper.writeValueAsString(cityCountry)); + } catch (JsonProcessingException e) { + e.printStackTrace(System.out); + } + } - long startMysql = System.currentTimeMillis(); - cityDataProcessing.testMysqlData(ids); - long stopMysql = System.currentTimeMillis(); + } + } - System.out.printf("%s:\t%d ms\n", "Redis", (stopRedis - startRedis)); - System.out.printf("%s:\t%d ms\n", "MySQL", (stopMysql - startMysql)); + private void testRedisData(List ids) { + try (StatefulRedisConnection connection = redisClient.connect()) { + RedisStringCommands sync = connection.sync(); + for (Integer id : ids) { + String value = sync.get(String.valueOf(id)); + try { + mapper.readValue(value, CityCountry.class); + } catch (JsonProcessingException e) { + e.printStackTrace(System.out); + } + } + } + } - main.shutdown(); + public void testMysqlData(List ids) { + try (Session session = sessionFactory.getCurrentSession()) { + session.beginTransaction(); + for (Integer id : ids) { + City city = cityService.getById(id); + Set languages = city.getCountryId().getLanguages(); + } + session.getTransaction().commit(); + } } + public List fetchData() { + try (Session session = sessionFactory.getCurrentSession()) { + List allCities = new ArrayList<>(); + session.beginTransaction(); + + countryService.getAll(); + + int totalCount = cityService.getTotalCount(); + int step = 500; + for (int i = 0; i < totalCount; i += step) { + allCities.addAll(cityService.getItems(i, step)); + } + session.getTransaction().commit(); + return allCities; + } + } } From 2d87e84e038b38b6d0b9941e23a19f3e0babcc92 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Sun, 6 Oct 2024 15:57:45 +0200 Subject: [PATCH 42/48] style: remove unnecessary code --- .../com/javarush/cache/RedisRepository.java | 33 +------ .../java/com/javarush/CityServiceTest.java | 97 ------------------- .../java/com/javarush/CountryServiceTest.java | 54 ----------- .../java/com/javarush/RedisServiceTest.java | 70 ------------- 4 files changed, 2 insertions(+), 252 deletions(-) delete mode 100644 src/test/java/com/javarush/CityServiceTest.java delete mode 100644 src/test/java/com/javarush/CountryServiceTest.java delete mode 100644 src/test/java/com/javarush/RedisServiceTest.java diff --git a/src/main/java/com/javarush/cache/RedisRepository.java b/src/main/java/com/javarush/cache/RedisRepository.java index f16b382..d1f4cc8 100644 --- a/src/main/java/com/javarush/cache/RedisRepository.java +++ b/src/main/java/com/javarush/cache/RedisRepository.java @@ -49,7 +49,7 @@ private String serialize(T entity) { try { return objectMapper.writeValueAsString(entity); } catch (Exception e) { - LOGGER.error("Error serializing object: " + e.getMessage()); + LOGGER.error("Error serializing object: {}", e.getMessage()); return null; } } @@ -58,37 +58,8 @@ private T deserialize(String serializedEntity, Class clazz) { try { return objectMapper.readValue(serializedEntity, clazz); } catch (Exception e) { - LOGGER.error("Error deserializing object: " + e.getMessage()); + LOGGER.error("Error deserializing object: {}", e.getMessage()); return null; } } } - -/*public void save(String key, T entity) { - jedis.set(key, serialize(entity)); - -public void delete(String key) { - jedis.del(key); - } - - public List getAll(String listName, Class clazz) { - List str = jedis.lrange(listName, 0, -1); - List typeClass = new ArrayList<>(); - for (String s : str) { - typeClass.add(deserialize(s, clazz)); - } - return typeClass; - } - - public List getItems(String listName, int offset, int limit, Class clazz) { - List str = jedis.lrange(listName, offset, limit - 1); - List typeClass = new ArrayList<>(); - for (String s : str) { - typeClass.add(deserialize(s, clazz)); - } - return typeClass; - } - - public int getTotalCount(String listName) { - return Math.toIntExact(jedis.llen(listName)); - }*/ diff --git a/src/test/java/com/javarush/CityServiceTest.java b/src/test/java/com/javarush/CityServiceTest.java deleted file mode 100644 index b70aa70..0000000 --- a/src/test/java/com/javarush/CityServiceTest.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.javarush; - -import static org.mockito.Mockito.*; -import static org.junit.jupiter.api.Assertions.*; - -import com.javarush.domain.entity.City; -import com.javarush.services.CityService; -import com.javarush.services.CountryService; -import org.hibernate.Transaction; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.query.Query; -import java.util.Arrays; -import java.util.List; - -public class CityServiceTest { - - @Mock - private SessionFactory sessionFactory; - - @Mock - private Session session; - - @Mock - private Transaction transaction; - - @Mock - private Query cityQuery; - - @Mock - private Query countQuery; - - @Mock - private CountryService countryService; - - @InjectMocks - private CityService cityService; - - @BeforeEach - public void setUp() { - MockitoAnnotations.openMocks(this); - when(sessionFactory.getCurrentSession()).thenReturn(session); - when(session.getTransaction()).thenReturn(transaction); - } - - @Test - public void testGetItems() { - City city1 = new City(); - City city2 = new City(); - List expectedCities = Arrays.asList(city1, city2); - - when(session.createQuery("select c from City c", City.class)).thenReturn(cityQuery); - when(cityQuery.setFirstResult(anyInt())).thenReturn(cityQuery); - when(cityQuery.setMaxResults(anyInt())).thenReturn(cityQuery); - when(cityQuery.list()).thenReturn(expectedCities); - - List actualCities = cityService.getItems(0, 10); - - assertEquals(expectedCities, actualCities); - verify(session).createQuery("select c from City c", City.class); - verify(cityQuery).setFirstResult(0); - verify(cityQuery).setMaxResults(10); - verify(cityQuery).list(); - } - - @Test - public void testGetTotalCount() { - when(session.createQuery("select count(c) from City c", Long.class)).thenReturn(countQuery); - when(countQuery.uniqueResult()).thenReturn(100L); - - int totalCount = cityService.getTotalCount(); - - assertEquals(100, totalCount); - verify(session).createQuery("select count(c) from City c", Long.class); - verify(countQuery).uniqueResult(); - } - - @Test - public void testGetById() { - City expectedCity = new City(); - when(session.createQuery("select c from City c join fetch c.countryId where c.id = :ID", City.class)).thenReturn(cityQuery); - when(cityQuery.setParameter("ID", 1)).thenReturn(cityQuery); - when(cityQuery.getSingleResult()).thenReturn(expectedCity); - - City actualCity = cityService.getById(1); - - assertEquals(expectedCity, actualCity); - verify(session).createQuery("select c from City c join fetch c.countryId where c.id = :ID", City.class); - verify(cityQuery).setParameter("ID", 1); - verify(cityQuery).getSingleResult(); - } -} \ No newline at end of file diff --git a/src/test/java/com/javarush/CountryServiceTest.java b/src/test/java/com/javarush/CountryServiceTest.java deleted file mode 100644 index 88f7860..0000000 --- a/src/test/java/com/javarush/CountryServiceTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.javarush; - -import static org.mockito.Mockito.*; -import static org.junit.jupiter.api.Assertions.*; - -import com.javarush.domain.entity.Country; -import com.javarush.services.CountryService; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.query.Query; -import java.util.Arrays; -import java.util.List; - -class CountryServiceTest { - @Mock - private SessionFactory sessionFactory; - - @Mock - private Session session; - - @Mock - private Query query; - - @InjectMocks - private CountryService countryService; - - @BeforeEach - public void setUp() { - MockitoAnnotations.openMocks(this); - when(sessionFactory.getCurrentSession()).thenReturn(session); - } - - @Test - public void testGetAll() { - Country country1 = new Country(); - Country country2 = new Country(); - List expectedCountries = Arrays.asList(country1, country2); - - when(session.createQuery("select c from Country c join fetch c.languages", Country.class)).thenReturn(query); - when(query.list()).thenReturn(expectedCountries); - - List actualCountries = countryService.getAll(); - - assertEquals(expectedCountries, actualCountries); - verify(sessionFactory).getCurrentSession(); - verify(session).createQuery("select c from Country c join fetch c.languages", Country.class); - verify(query).list(); - } -} \ No newline at end of file diff --git a/src/test/java/com/javarush/RedisServiceTest.java b/src/test/java/com/javarush/RedisServiceTest.java deleted file mode 100644 index 410379b..0000000 --- a/src/test/java/com/javarush/RedisServiceTest.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.javarush; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.javarush.redis.CityCountry; -import com.javarush.services.RedisService; -import io.lettuce.core.RedisClient; -import io.lettuce.core.api.StatefulRedisConnection; -import io.lettuce.core.api.sync.RedisCommands; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.util.List; - -import static org.mockito.Mockito.*; - -class RedisServiceTest { - @Mock - private RedisClient redisClient; - - @Mock - private StatefulRedisConnection connection; - - @Mock - private RedisCommands syncCommands; - - @InjectMocks - private RedisService redisService; - - private final ObjectMapper mapper = new ObjectMapper(); - - @BeforeEach - public void setUp() { - MockitoAnnotations.openMocks(this); - when(redisClient.connect()).thenReturn(connection); - when(connection.sync()).thenReturn(syncCommands); - } - - @Test - public void testPushToRedis() throws JsonProcessingException { - CityCountry cityCountry = new CityCountry(); - cityCountry.setId(1); - cityCountry.setName("Test City"); - - List data = List.of(cityCountry); - - redisService.pushToRedis(data); - - verify(syncCommands, times(1)).set(eq("1"), eq(mapper.writeValueAsString(cityCountry))); - } - - @Test - public void testTestRedisData() throws JsonProcessingException { - CityCountry cityCountry = new CityCountry(); - cityCountry.setId(1); - cityCountry.setName("Test City"); - - String cityCountryJson = mapper.writeValueAsString(cityCountry); - when(syncCommands.get("1")).thenReturn(cityCountryJson); - - List ids = List.of(1); - - redisService.testRedisData(ids); - - verify(syncCommands, times(1)).get("1"); - } -} \ No newline at end of file From 5eddd8d501e80628f52636a9d69990c4e1e1f58d Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Sun, 6 Oct 2024 18:50:09 +0200 Subject: [PATCH 43/48] fix: bugs fixes --- .../java/com/javarush/DataTransformer.java | 8 +++---- src/main/java/com/javarush/Main.java | 24 +++++++++---------- .../javarush/repository/CityRepository.java | 12 +++++----- .../repository/CountryRepository.java | 10 ++------ .../com/javarush/services/CityService.java | 11 +++++---- .../com/javarush/services/CountryService.java | 11 +++++---- 6 files changed, 36 insertions(+), 40 deletions(-) diff --git a/src/main/java/com/javarush/DataTransformer.java b/src/main/java/com/javarush/DataTransformer.java index 797a502..9803fe7 100644 --- a/src/main/java/com/javarush/DataTransformer.java +++ b/src/main/java/com/javarush/DataTransformer.java @@ -10,7 +10,7 @@ import java.util.stream.Collectors; public class DataTransformer { - public CityCountry countryTransformToCityCountry(Country country) { + public static CityCountry countryTransformToCityCountry(Country country) { CityCountry res = new CityCountry(); res.setAlternativeCountryCode(country.getCode2()); res.setContinent(country.getContinent()); @@ -31,7 +31,7 @@ public CityCountry countryTransformToCityCountry(Country country) { return res; } - public CityCountry cityTransformToCityCountry(City city) { + public static CityCountry cityTransformToCityCountry(City city) { CityCountry res = new CityCountry(); res.setId(city.getId()); res.setName(city.getName()); @@ -40,7 +40,7 @@ public CityCountry cityTransformToCityCountry(City city) { return res; } - public City cityCountryTransformToCity(CityCountry cityCountry) { + public static City cityCountryTransformToCity(CityCountry cityCountry) { City city = new City(); city.setId(cityCountry.getId()); city.setName(cityCountry.getName()); @@ -49,7 +49,7 @@ public City cityCountryTransformToCity(CityCountry cityCountry) { return city; } - public Country cityCountryToCountry(CityCountry cityCountry) { + public static Country cityCountryToCountry(CityCountry cityCountry) { Country country = new Country(); country.setCode2(cityCountry.getAlternativeCountryCode()); country.setContinent(cityCountry.getContinent()); diff --git a/src/main/java/com/javarush/Main.java b/src/main/java/com/javarush/Main.java index 338b4b0..1eb7c23 100644 --- a/src/main/java/com/javarush/Main.java +++ b/src/main/java/com/javarush/Main.java @@ -8,6 +8,8 @@ import com.javarush.domain.entity.City; import com.javarush.domain.entity.CountryLanguage; import com.javarush.redis.CityCountry; +import com.javarush.repository.CityRepository; +import com.javarush.repository.CountryRepository; import com.javarush.services.CityService; import com.javarush.services.CountryService; import io.lettuce.core.RedisClient; @@ -23,17 +25,17 @@ import static java.util.Objects.nonNull; public class Main { - private final SessionFactory sessionFactory; - private final RedisClient redisClient; - private final CityService cityService; - private final CountryService countryService; - private final ObjectMapper mapper; + public final SessionFactory sessionFactory; + public final RedisClient redisClient; + public final CityService cityService; + public final CountryService countryService; + public final ObjectMapper mapper; public Main() { sessionFactory = HibernateUtil.getSessionFactory(); redisClient = RedisConfig.prepareRedisClient(); - cityService = new CityService(); - countryService = new CountryService(); + cityService = new CityService(new RedisRepository(), new CityRepository()); + countryService = new CountryService(new RedisRepository(), new CountryRepository()); mapper = new ObjectMapper(); } @@ -47,16 +49,14 @@ private void shutdown() { } public static void main(String[] args) { + Main main = new Main(); RedisRepository countryRedisRepository = new RedisRepository(); RedisRepository cityRedisRepository = new RedisRepository(); - CountryService countryService = new CountryService(); - CityService cityService = new CityService(); - System.out.println("Querying Country by ID..."); for (int i = 0; i < 15; i++) { - countryService.getById(1); - cityService.getById(2); + main.countryService.getById(1); + main.cityService.getById(2); } } diff --git a/src/main/java/com/javarush/repository/CityRepository.java b/src/main/java/com/javarush/repository/CityRepository.java index dc6e275..0420776 100644 --- a/src/main/java/com/javarush/repository/CityRepository.java +++ b/src/main/java/com/javarush/repository/CityRepository.java @@ -22,7 +22,7 @@ public City getById(Integer id) { @Override public City save(City entity) { - try (Session session = sessionFactory.openSession()) { + try (Session session = sessionFactory.getCurrentSession()) { Transaction transaction = session.beginTransaction(); session.persist(entity); transaction.commit(); @@ -32,25 +32,25 @@ public City save(City entity) { @Override public void delete(Integer id) { - try (Session session = sessionFactory.openSession()) { - session.beginTransaction(); + try (Session session = sessionFactory.getCurrentSession()) { + Transaction transaction = session.beginTransaction(); session.createQuery("delete from City c where c.id = :ID", City.class) .setParameter("ID", id) .executeUpdate(); - session.getTransaction().commit(); + transaction.commit(); } } @Override public List getAll() { - try (Session session = sessionFactory.getCurrentSession()) { + try (Session session = sessionFactory.openSession()) { return session.createQuery("select c from City c", City.class).list(); } } @Override public List getItems(int offset, int limit) { - try(Session session = sessionFactory.getCurrentSession()) { + try(Session session = sessionFactory.openSession()) { return session.createQuery("select c from City c", City.class) .setFirstResult(offset) .setMaxResults(limit) diff --git a/src/main/java/com/javarush/repository/CountryRepository.java b/src/main/java/com/javarush/repository/CountryRepository.java index 64ec52e..7207b59 100644 --- a/src/main/java/com/javarush/repository/CountryRepository.java +++ b/src/main/java/com/javarush/repository/CountryRepository.java @@ -50,23 +50,17 @@ public List getAll() { @Override public List getItems(int offset, int limit) { try (Session session = sessionFactory.getCurrentSession()) { - session.beginTransaction(); - List countryList = session.createQuery("select c from Country c", Country.class) + return session.createQuery("select c from Country c", Country.class) .setFirstResult(offset) .setMaxResults(limit) .list(); - session.getTransaction().commit(); - return countryList; } } @Override public int getTotalCount() { try (Session session = sessionFactory.getCurrentSession()) { - session.beginTransaction(); - int intExact = Math.toIntExact(session.createQuery("select count(c) from Country c", Long.class).uniqueResult()); - session.getTransaction().commit(); - return intExact; + return Math.toIntExact(session.createQuery("select count(c) from Country c", Long.class).uniqueResult()); } } } diff --git a/src/main/java/com/javarush/services/CityService.java b/src/main/java/com/javarush/services/CityService.java index 126cdee..6f42db4 100644 --- a/src/main/java/com/javarush/services/CityService.java +++ b/src/main/java/com/javarush/services/CityService.java @@ -6,26 +6,27 @@ import com.javarush.domain.exceptions.CityException; import com.javarush.redis.CityCountry; import com.javarush.repository.CityRepository; +import lombok.RequiredArgsConstructor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.List; +@RequiredArgsConstructor public class CityService { private static final Logger LOGGER = LoggerFactory.getLogger(CityService.class); - private final RedisRepository redisRepository = new RedisRepository(); - private final CityRepository cityRepository = new CityRepository(); - private final DataTransformer dataTransformer = new DataTransformer(); + private final RedisRepository redisRepository; + private final CityRepository cityRepository; public City getById(Integer id) { String key = "city_" + id; try { if(redisRepository.checkExists(key)){ CityCountry cityCountry = redisRepository.getById(key, CityCountry.class); - return dataTransformer.cityCountryTransformToCity(cityCountry); + return DataTransformer.cityCountryTransformToCity(cityCountry); } City city = cityRepository.getById(id); - redisRepository.put(key, dataTransformer.cityTransformToCityCountry(city)); + redisRepository.put(key, DataTransformer.cityTransformToCityCountry(city)); return city; } catch (Exception e) { LOGGER.error("Cannot get city with id {}", id); diff --git a/src/main/java/com/javarush/services/CountryService.java b/src/main/java/com/javarush/services/CountryService.java index 60867ec..757c4ad 100644 --- a/src/main/java/com/javarush/services/CountryService.java +++ b/src/main/java/com/javarush/services/CountryService.java @@ -6,26 +6,27 @@ import com.javarush.domain.exceptions.CountryException; import com.javarush.redis.CityCountry; import com.javarush.repository.CountryRepository; +import lombok.RequiredArgsConstructor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.List; +@RequiredArgsConstructor public class CountryService { private static final Logger LOGGER = LoggerFactory.getLogger(CountryService.class); - private final RedisRepository redisRepository = new RedisRepository(); - private final CountryRepository countryRepository = new CountryRepository(); - private final DataTransformer dataTransformer = new DataTransformer(); + private final RedisRepository redisRepository; + private final CountryRepository countryRepository; public Country getById(Integer id) { String key = "country_" + id; try { if (redisRepository.checkExists(key)) { CityCountry cityCountry = redisRepository.getById(key, CityCountry.class); - return dataTransformer.cityCountryToCountry(cityCountry); + return DataTransformer.cityCountryToCountry(cityCountry); } Country country = countryRepository.getById(id); - redisRepository.put(key, dataTransformer.countryTransformToCityCountry(country)); + redisRepository.put(key, DataTransformer.countryTransformToCityCountry(country)); return country; } catch (Exception e) { LOGGER.error("Cannot get country with id {}", id); From 3422b1025daca67be7f159ae0e11c800b1307d28 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Sun, 6 Oct 2024 18:50:28 +0200 Subject: [PATCH 44/48] test: add test class --- .../javarush/services/CityServiceTest.java | 115 +++++++++++++++++ .../javarush/services/CountryServiceTest.java | 116 ++++++++++++++++++ 2 files changed, 231 insertions(+) create mode 100644 src/test/java/com/javarush/services/CityServiceTest.java create mode 100644 src/test/java/com/javarush/services/CountryServiceTest.java diff --git a/src/test/java/com/javarush/services/CityServiceTest.java b/src/test/java/com/javarush/services/CityServiceTest.java new file mode 100644 index 0000000..8397e5c --- /dev/null +++ b/src/test/java/com/javarush/services/CityServiceTest.java @@ -0,0 +1,115 @@ +package com.javarush.services; + +import com.javarush.DataTransformer; +import com.javarush.cache.RedisRepository; +import com.javarush.domain.entity.City; +import com.javarush.domain.exceptions.CityException; +import com.javarush.redis.CityCountry; +import com.javarush.repository.CityRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class CityServiceTest { + + @Mock + private RedisRepository redisRepository; + + @Mock + private CityRepository cityRepository; + + @InjectMocks + private CityService cityService; + + private City city; + + @BeforeEach + void setUp() { + MockitoAnnotations.initMocks(this); + city = new City(); + } + + @Test + void testGetById_CityExistsInRedis() { + int id = 1; + String key = "city_" + id; + CityCountry testCityCountry = DataTransformer.cityTransformToCityCountry(city); + + when(redisRepository.checkExists(key)).thenReturn(true); + when(redisRepository.getById(key, CityCountry.class)).thenReturn(testCityCountry); + + City city = cityService.getById(id); + + assertNotNull(city); + assertEquals(city.getId(), city.getId()); + verify(redisRepository, times(1)).getById(key, CityCountry.class); + } + + @Test + void testGetById_CityNotInRedis() throws Exception { + int cityId = 1; + String key = "city_" + cityId; + + when(redisRepository.checkExists(key)).thenReturn(false); + when(cityRepository.getById(cityId)).thenReturn(city); + + City result = cityService.getById(cityId); + + assertNotNull(result); + verify(redisRepository, times(1)).put(eq(key), any(CityCountry.class)); + assertEquals(city, result); + } + + @Test + void testGetById_ExceptionThrown() { + int cityId = 1; + String key = "city_" + cityId; + + when(redisRepository.checkExists(key)).thenThrow(new RuntimeException("Test exception")); + + Exception exception = assertThrows(CityException.class, () -> cityService.getById(cityId)); + assertTrue(exception.getMessage().contains("ERROR :: cannot get city with id")); + } + + @Test + void testSave_Successful() throws Exception { + when(cityRepository.save(city)).thenReturn(city); + + City result = cityService.save(city); + + assertNotNull(result); + assertEquals(city, result); + } + + @Test + void testSave_ExceptionThrown() { + when(cityRepository.save(city)).thenThrow(new RuntimeException("Test exception")); + + Exception exception = assertThrows(CityException.class, () -> cityService.save(city)); + assertTrue(exception.getMessage().contains("ERROR :: cannot save city with id")); + } + + @Test + void testDelete_Successful() throws Exception { + int cityId = 1; + + doNothing().when(cityRepository).delete(cityId); + + assertDoesNotThrow(() -> cityService.delete(cityId)); + } + + @Test + void testDelete_ExceptionThrown() { + int cityId = 1; + + doThrow(new RuntimeException("Test exception")).when(cityRepository).delete(cityId); + + Exception exception = assertThrows(CityException.class, () -> cityService.delete(cityId)); + assertTrue(exception.getMessage().contains("ERROR :: cannot delete city with id")); + } +} \ No newline at end of file diff --git a/src/test/java/com/javarush/services/CountryServiceTest.java b/src/test/java/com/javarush/services/CountryServiceTest.java new file mode 100644 index 0000000..332a40d --- /dev/null +++ b/src/test/java/com/javarush/services/CountryServiceTest.java @@ -0,0 +1,116 @@ +package com.javarush.services; + +import com.javarush.DataTransformer; +import com.javarush.cache.RedisRepository; +import com.javarush.domain.entity.Country; +import com.javarush.domain.exceptions.CountryException; +import com.javarush.redis.CityCountry; +import com.javarush.repository.CountryRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; + +class CountryServiceTest { + @Mock + private RedisRepository redisRepository; + + @Mock + private CountryRepository countryRepository; + + @InjectMocks + private CountryService countryService; + + private Country country; + + @BeforeEach + void setUp() { + MockitoAnnotations.initMocks(this); + country = new Country(); + } + + @Test + void testGetById_CountryExistsInRedis() { + int id = 1; + String key = "country_" + id; + CityCountry testCityCountry = DataTransformer.countryTransformToCityCountry(country); + + when(redisRepository.checkExists(key)).thenReturn(true); + when(redisRepository.getById(key, CityCountry.class)).thenReturn(testCityCountry); + + Country country1 = countryService.getById(id); + + assertNotNull(country1); + assertEquals(country1, country); + verify(redisRepository, times(1)).getById(key, CityCountry.class); + } + + @Test + void testGetById_CountryNotInRedis() throws Exception { + int countryId = 1; + String key = "country_" + countryId; + + when(redisRepository.checkExists(key)).thenReturn(false); + when(countryRepository.getById(countryId)).thenReturn(country); + + Country result = countryService.getById(countryId); + + assertNotNull(result); + verify(redisRepository, times(1)).put(eq(key), any(CityCountry.class)); + assertEquals(country, result); + } + + @Test + void testGetById_ExceptionThrown() { + int countryId = 1; + String key = "country_" + countryId; + + when(redisRepository.checkExists(key)).thenThrow(new RuntimeException("Test exception")); + + Exception exception = assertThrows(CountryException.class, () -> countryService.getById(countryId)); + assertTrue(exception.getMessage().contains("ERROR :: cannot get country with id")); + } + + @Test + void testSave_Successful() throws Exception { + when(countryRepository.save(country)).thenReturn(country); + + Country result = countryService.save(country); + + assertNotNull(result); + assertEquals(country, result); + } + + @Test + void testSave_ExceptionThrown() { + when(countryRepository.save(country)).thenThrow(new RuntimeException("Test exception")); + + Exception exception = assertThrows(CountryException.class, () -> countryService.save(country)); + assertTrue(exception.getMessage().contains("ERROR :: could not save country with id")); + } + + @Test + void testDelete_Successful() throws Exception { + int countryId = 1; + + doNothing().when(countryRepository).delete(countryId); + + assertDoesNotThrow(() -> countryService.delete(countryId)); + } + + @Test + void testDelete_ExceptionThrown() { + int countryId = 1; + + doThrow(new RuntimeException("Test exception")).when(countryRepository).delete(countryId); + + Exception exception = assertThrows(CountryException.class, () -> countryService.delete(countryId)); + assertTrue(exception.getMessage().contains("ERROR :: cannot delete country with id")); + } +} \ No newline at end of file From 30f8b6ae03ffe5b54ee3263836619e44ca4e824c Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Tue, 8 Oct 2024 19:52:00 +0200 Subject: [PATCH 45/48] refactor: remove catches --- .../com/javarush/cache/RedisRepository.java | 29 +++++++------------ .../javarush/services/CityServiceTest.java | 3 +- .../javarush/services/CountryServiceTest.java | 3 +- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/javarush/cache/RedisRepository.java b/src/main/java/com/javarush/cache/RedisRepository.java index d1f4cc8..4803997 100644 --- a/src/main/java/com/javarush/cache/RedisRepository.java +++ b/src/main/java/com/javarush/cache/RedisRepository.java @@ -1,5 +1,6 @@ package com.javarush.cache; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.javarush.services.CityService; import org.slf4j.Logger; @@ -13,9 +14,11 @@ public class RedisRepository { private static final String TOPK_NAME = "city-country"; private static final int THRESHOLD = 7; private static final Logger LOGGER = LoggerFactory.getLogger(CityService.class); + private static final String REDIS_URL = "redis://127.0.0.1:6379"; + private static final String BRACES_REGEX = "[\\[\\]]"; public RedisRepository() { - jedis = new UnifiedJedis("redis://127.0.0.1:6379"); + jedis = new UnifiedJedis(REDIS_URL); jedis.del(TOPK_NAME); if (!jedis.exists(TOPK_NAME)) { @@ -23,12 +26,12 @@ public RedisRepository() { } } - public T getById(String key, Class clazz) { + public T getById(String key, Class clazz) throws JsonProcessingException { String serializedEntity = jedis.get(key); return deserialize(serializedEntity, clazz); } - public void put(String key, T value) { + public void put(String key, T value) throws JsonProcessingException { jedis.topkAdd(TOPK_NAME, key); if (getCount(key) >= THRESHOLD) { @@ -38,28 +41,18 @@ public void put(String key, T value) { private int getCount(String key) { String count = jedis.sendCommand(() -> SafeEncoder.encode("TOPK.COUNT"), SafeEncoder.encodeMany(TOPK_NAME, key)).toString(); - return Integer.parseInt(count.replaceAll("[\\[\\]]", "")); + return Integer.parseInt(count.replaceAll(BRACES_REGEX, "")); } public boolean checkExists(String key) { return jedis.exists(key); } - private String serialize(T entity) { - try { - return objectMapper.writeValueAsString(entity); - } catch (Exception e) { - LOGGER.error("Error serializing object: {}", e.getMessage()); - return null; - } + private String serialize(T entity) throws JsonProcessingException { + return objectMapper.writeValueAsString(entity); } - private T deserialize(String serializedEntity, Class clazz) { - try { - return objectMapper.readValue(serializedEntity, clazz); - } catch (Exception e) { - LOGGER.error("Error deserializing object: {}", e.getMessage()); - return null; - } + private T deserialize(String serializedEntity, Class clazz) throws JsonProcessingException { + return objectMapper.readValue(serializedEntity, clazz); } } diff --git a/src/test/java/com/javarush/services/CityServiceTest.java b/src/test/java/com/javarush/services/CityServiceTest.java index 8397e5c..f90b4a8 100644 --- a/src/test/java/com/javarush/services/CityServiceTest.java +++ b/src/test/java/com/javarush/services/CityServiceTest.java @@ -1,5 +1,6 @@ package com.javarush.services; +import com.fasterxml.jackson.core.JsonProcessingException; import com.javarush.DataTransformer; import com.javarush.cache.RedisRepository; import com.javarush.domain.entity.City; @@ -35,7 +36,7 @@ void setUp() { } @Test - void testGetById_CityExistsInRedis() { + void testGetById_CityExistsInRedis() throws JsonProcessingException { int id = 1; String key = "city_" + id; CityCountry testCityCountry = DataTransformer.cityTransformToCityCountry(city); diff --git a/src/test/java/com/javarush/services/CountryServiceTest.java b/src/test/java/com/javarush/services/CountryServiceTest.java index 332a40d..2d34758 100644 --- a/src/test/java/com/javarush/services/CountryServiceTest.java +++ b/src/test/java/com/javarush/services/CountryServiceTest.java @@ -1,5 +1,6 @@ package com.javarush.services; +import com.fasterxml.jackson.core.JsonProcessingException; import com.javarush.DataTransformer; import com.javarush.cache.RedisRepository; import com.javarush.domain.entity.Country; @@ -36,7 +37,7 @@ void setUp() { } @Test - void testGetById_CountryExistsInRedis() { + void testGetById_CountryExistsInRedis() throws JsonProcessingException { int id = 1; String key = "country_" + id; CityCountry testCityCountry = DataTransformer.countryTransformToCityCountry(country); From f0bd4205ca3c53632abf6f01505dc9642d27236a Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Tue, 8 Oct 2024 19:52:21 +0200 Subject: [PATCH 46/48] refactor: edit logs --- src/main/java/com/javarush/services/CityService.java | 12 ++++++------ .../java/com/javarush/services/CountryService.java | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/javarush/services/CityService.java b/src/main/java/com/javarush/services/CityService.java index 6f42db4..86d90fa 100644 --- a/src/main/java/com/javarush/services/CityService.java +++ b/src/main/java/com/javarush/services/CityService.java @@ -29,7 +29,7 @@ public City getById(Integer id) { redisRepository.put(key, DataTransformer.cityTransformToCityCountry(city)); return city; } catch (Exception e) { - LOGGER.error("Cannot get city with id {}", id); + LOGGER.error("Cannot get city with id : {} ", id, e); throw new CityException("ERROR :: cannot get city with id " + id + " " + e.getMessage()); } } @@ -43,7 +43,7 @@ public City save(City entity) { } return city; } catch (Exception e) { - LOGGER.error("Cannot save city with id {}", entity.getId()); + LOGGER.error("Cannot save city with id {}", entity.getId(), e); throw new CityException("ERROR :: cannot save city with id " + entity.getId() + " " + e.getMessage()); } } @@ -52,7 +52,7 @@ public void delete(Integer id) { try { new CityRepository().delete(id); } catch (Exception e) { - LOGGER.error("Cannot delete city with id: {}", id); + LOGGER.error("Cannot delete city with id: {}", id, e); throw new CityException("ERROR :: cannot delete city with id: " + id + " " + e.getMessage()); } } @@ -66,7 +66,7 @@ public List getAll() { } return cities; } catch (Exception e) { - LOGGER.error("Cannot get all cities"); + LOGGER.error("Cannot get all cities : ", e); throw new CityException("ERROR :: cannot get all cities: " + e.getMessage()); } } @@ -80,7 +80,7 @@ public List getItems(int offset, int limit) { } return cities; } catch (Exception e) { - LOGGER.error("Cannot get all cities in range"); + LOGGER.error("Cannot get all cities in range : ", e); throw new CityException("ERROR :: cannot get all cities in range: " + e.getMessage()); } } @@ -94,7 +94,7 @@ public int getTotalCount() { } return totalCount; } catch (Exception e) { - LOGGER.error("Cannot get all cities count"); + LOGGER.error("Cannot get all cities count : ", e); throw new CityException("ERROR :: cannot get all cities count: " + e.getMessage()); } } diff --git a/src/main/java/com/javarush/services/CountryService.java b/src/main/java/com/javarush/services/CountryService.java index 757c4ad..ba244b0 100644 --- a/src/main/java/com/javarush/services/CountryService.java +++ b/src/main/java/com/javarush/services/CountryService.java @@ -29,7 +29,7 @@ public Country getById(Integer id) { redisRepository.put(key, DataTransformer.countryTransformToCityCountry(country)); return country; } catch (Exception e) { - LOGGER.error("Cannot get country with id {}", id); + LOGGER.error("Cannot get country with id {}", id, e); throw new CountryException("ERROR :: cannot get country with id " + id + " " + e.getMessage()); } } @@ -52,7 +52,7 @@ public void delete(Integer id) { try { countryRepository.delete(id); } catch (Exception e) { - LOGGER.error("Cannot delete country with id: {}", id); + LOGGER.error("Cannot delete country with id: {}", id, e); throw new CountryException("ERROR :: cannot delete country with id: " + id + " " + e.getMessage()); } } @@ -66,7 +66,7 @@ public List getAll() { } return countries; } catch (Exception e) { - LOGGER.error("Cannot get all countries"); + LOGGER.error("Cannot get all countries : ", e); throw new CountryException("ERROR :: cannot get all countries: " + e.getMessage()); } } @@ -80,7 +80,7 @@ public List getItems(int offset, int limit) { } return countries; } catch (Exception e) { - LOGGER.error("Cannot get all countries in range"); + LOGGER.error("Cannot get all countries in range : ", e); throw new CountryException("ERROR :: cannot get all countries in range: " + e.getMessage()); } } @@ -94,7 +94,7 @@ public int getTotalCount() { } return totalCount; } catch (Exception e) { - LOGGER.error("Cannot get all countries count"); + LOGGER.error("Cannot get all countries count : ", e); throw new CountryException("ERROR :: cannot get all countries count: " + e.getMessage()); } } From 18f463ff318a7cf41029d459117678cd917bf9e3 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Tue, 8 Oct 2024 19:52:29 +0200 Subject: [PATCH 47/48] refactor: edit pom.xml --- pom.xml | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/pom.xml b/pom.xml index 5e52653..28d595e 100644 --- a/pom.xml +++ b/pom.xml @@ -12,19 +12,6 @@ 8 - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - 20 - 20 - - - - @@ -89,4 +76,18 @@ 5.2.0 + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 21 + 21 + + + + From ce4838bb06a7baf941f6a865bc7c569672a07511 Mon Sep 17 00:00:00 2001 From: Anastasiia Dosyn Date: Tue, 8 Oct 2024 19:53:06 +0200 Subject: [PATCH 48/48] refactor: edit main --- .../javarush/{Main.java => Application.java} | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) rename src/main/java/com/javarush/{Main.java => Application.java} (87%) diff --git a/src/main/java/com/javarush/Main.java b/src/main/java/com/javarush/Application.java similarity index 87% rename from src/main/java/com/javarush/Main.java rename to src/main/java/com/javarush/Application.java index 1eb7c23..56c48c5 100644 --- a/src/main/java/com/javarush/Main.java +++ b/src/main/java/com/javarush/Application.java @@ -17,6 +17,8 @@ import io.lettuce.core.api.sync.RedisStringCommands; import org.hibernate.Session; import org.hibernate.SessionFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; @@ -24,14 +26,15 @@ import static java.util.Objects.nonNull; -public class Main { +public class Application { public final SessionFactory sessionFactory; public final RedisClient redisClient; public final CityService cityService; public final CountryService countryService; public final ObjectMapper mapper; + private static final Logger LOGGER = LoggerFactory.getLogger(Application.class); - public Main() { + public Application() { sessionFactory = HibernateUtil.getSessionFactory(); redisClient = RedisConfig.prepareRedisClient(); cityService = new CityService(new RedisRepository(), new CityRepository()); @@ -49,14 +52,15 @@ private void shutdown() { } public static void main(String[] args) { - Main main = new Main(); + int numOfQueries = 15; + Application application = new Application(); RedisRepository countryRedisRepository = new RedisRepository(); RedisRepository cityRedisRepository = new RedisRepository(); System.out.println("Querying Country by ID..."); - for (int i = 0; i < 15; i++) { - main.countryService.getById(1); - main.cityService.getById(2); + for (int i = 0; i < numOfQueries; i++) { + application.countryService.getById(1); + application.cityService.getById(2); } } @@ -67,6 +71,7 @@ private void pushToRedis(List data) { try { sync.set(String.valueOf(cityCountry.getId()), mapper.writeValueAsString(cityCountry)); } catch (JsonProcessingException e) { + LOGGER.error("Couldn't push to redis : ", e); e.printStackTrace(System.out); } } @@ -82,6 +87,7 @@ private void testRedisData(List ids) { try { mapper.readValue(value, CityCountry.class); } catch (JsonProcessingException e) { + LOGGER.error("Couldn't test redis data : ", e); e.printStackTrace(System.out); } }