diff --git a/.env.example b/.env.example index ca95628..bf790bb 100644 --- a/.env.example +++ b/.env.example @@ -1,11 +1,8 @@ # Copy this file to .env and customize the values for your environment # cp .env.example .env -# Couchbase configuration -COUCHBASE_CONNECTION_STRING=couchbase://localhost -COUCHBASE_USERNAME=admin -COUCHBASE_PASSWORD=your_password_here -COUCHBASE_BUCKET_NAME=store_scraper +# Redis configuration +REDIS_URL=localhost:6379 # Telegram Bot configuration TELEGRAM_BOT_TOKEN=your_telegram_bot_token_here diff --git a/build.gradle.kts b/build.gradle.kts index e3451cd..9bb2710 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -22,13 +22,15 @@ configurations { dependencies { annotationProcessor("org.projectlombok:lombok:1.18.36") - implementation("com.couchbase.client:java-client:3.4.11") + implementation("com.google.code.gson:gson:2.11.0") + implementation("com.google.guava:guava:33.4.0-jre") + implementation("org.apache.commons:commons-text:1.13.0") implementation("org.apache.logging.log4j:log4j-core:2.24.3") implementation("org.apache.logging.log4j:log4j-slf4j2-impl:2.24.3") - // implementation("org.telegram:telegrambots-abilities:8.0.0") implementation("org.telegram:telegrambots-client:8.0.0") implementation("org.telegram:telegrambots-extensions:8.0.0") implementation("org.telegram:telegrambots-longpolling:8.0.0") + implementation("redis.clients:jedis:5.2.0") testAnnotationProcessor("org.projectlombok:lombok:1.18.36") testImplementation(platform("org.junit:junit-bom:5.11.4")) diff --git a/compose.dev.yml b/compose.dev.yml index 4a2e505..3f4d356 100644 --- a/compose.dev.yml +++ b/compose.dev.yml @@ -1,18 +1,12 @@ services: - couchbase: - image: couchbase:community-7.6.2 - env_file: - - .env + redis: + image: redis:7.2-alpine ports: - - "8091-8097:8091-8097" - - "9123:9123" - - "11207:11207" - - "11210:11210" - - "11280:11280" - - "18091-18097:18091-18097" + - "6379:6379" volumes: - - couchbase_data:/opt/couchbase/var + - redis_data:/data restart: unless-stopped + command: redis-server --appendonly yes volumes: - couchbase_data: + redis_data: \ No newline at end of file diff --git a/compose.yml b/compose.yml index 2a951d5..8b86a6e 100644 --- a/compose.yml +++ b/compose.yml @@ -2,36 +2,6 @@ services: server: build: context: . - env_file: - - .env - depends_on: - - couchbase - hostname: couchbase - networks: - - internal - command: > - bash -c "couchbase-server -- -advertised_hostname couchbase" - couchbase: - image: couchbase:community-7.6.2 - # env_file: - # - .env - # ports: # Enable these ports if you need - # - "8091-8097:8091-8097" - # - "9123:9123" - # - "11207:11207" - # - "11210:11210" - # - "11280:11280" - # - "18091-18097:18091-18097" - volumes: - - couchbase_data:/opt/couchbase/var - restart: unless-stopped - networks: - - internal - -volumes: - couchbase_data: - -networks: - internal: - driver: bridge +# If you need redis, add redis service +# Check compose.dev.yml for example diff --git a/src/main/java/com/miti99/storescraperbot/api/apple/AppStoreScraper.java b/src/main/java/com/miti99/storescraperbot/api/apple/AppStoreScraper.java index a023f43..1e7370b 100644 --- a/src/main/java/com/miti99/storescraperbot/api/apple/AppStoreScraper.java +++ b/src/main/java/com/miti99/storescraperbot/api/apple/AppStoreScraper.java @@ -1,10 +1,8 @@ package com.miti99.storescraperbot.api.apple; -import com.couchbase.client.core.deps.io.netty.handler.codec.http.HttpHeaderNames; -import com.couchbase.client.core.deps.io.netty.handler.codec.http.HttpHeaderValues; import com.miti99.storescraperbot.api.apple.request.AppleAppRequest; import com.miti99.storescraperbot.api.apple.response.AppleAppResponse; -import com.miti99.storescraperbot.util.JacksonUtil; +import com.miti99.storescraperbot.util.GsonUtil; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpClient.Redirect; @@ -22,10 +20,8 @@ public class AppStoreScraper { HttpRequest.newBuilder() .uri(URI.create(BASE_URL + "/app")) // .timeout(Duration.ofMillis(TIMEOUT)) - .header( - HttpHeaderNames.CONTENT_TYPE.toString(), - HttpHeaderValues.APPLICATION_JSON.toString()) - .POST(BodyPublishers.ofString(JacksonUtil.writeValueAsString(request))) + .header("Content-Type", "application/json") + .POST(BodyPublishers.ofString(GsonUtil.toJson(request))) .build(); var body = @@ -35,6 +31,6 @@ public class AppStoreScraper { .build() .send(httpRequest, BodyHandlers.ofString()) .body(); - return JacksonUtil.readValue(body, AppleAppResponse.class); + return GsonUtil.fromJson(body, AppleAppResponse.class); } } diff --git a/src/main/java/com/miti99/storescraperbot/api/google/GooglePlayScraper.java b/src/main/java/com/miti99/storescraperbot/api/google/GooglePlayScraper.java index 4b12fc4..02b3c09 100644 --- a/src/main/java/com/miti99/storescraperbot/api/google/GooglePlayScraper.java +++ b/src/main/java/com/miti99/storescraperbot/api/google/GooglePlayScraper.java @@ -1,10 +1,8 @@ package com.miti99.storescraperbot.api.google; -import com.couchbase.client.core.deps.io.netty.handler.codec.http.HttpHeaderNames; -import com.couchbase.client.core.deps.io.netty.handler.codec.http.HttpHeaderValues; import com.miti99.storescraperbot.api.google.request.GoogleAppRequest; import com.miti99.storescraperbot.api.google.response.GoogleAppResponse; -import com.miti99.storescraperbot.util.JacksonUtil; +import com.miti99.storescraperbot.util.GsonUtil; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpClient.Redirect; @@ -22,10 +20,8 @@ public class GooglePlayScraper { HttpRequest.newBuilder() .uri(URI.create(BASE_URL + "/app")) // .timeout(Duration.ofMillis(TIMEOUT)) - .header( - HttpHeaderNames.CONTENT_TYPE.toString(), - HttpHeaderValues.APPLICATION_JSON.toString()) - .POST(BodyPublishers.ofString(JacksonUtil.writeValueAsString(request))) + .header("Content-Type", "application/json") + .POST(BodyPublishers.ofString(GsonUtil.toJson(request))) .build(); var body = @@ -35,6 +31,6 @@ public class GooglePlayScraper { .build() .send(httpRequest, BodyHandlers.ofString()) .body(); - return JacksonUtil.readValue(body, GoogleAppResponse.class); + return GsonUtil.fromJson(body, GoogleAppResponse.class); } } diff --git a/src/main/java/com/miti99/storescraperbot/config/Config.java b/src/main/java/com/miti99/storescraperbot/config/Config.java index 2ecc0d6..e89db87 100644 --- a/src/main/java/com/miti99/storescraperbot/config/Config.java +++ b/src/main/java/com/miti99/storescraperbot/config/Config.java @@ -8,11 +8,7 @@ import java.util.Set; import java.util.stream.Collectors; public class Config { - public static final String COUCHBASE_CONNECTION_STRING = - System.getenv("COUCHBASE_CONNECTION_STRING"); - public static final String COUCHBASE_USERNAME = System.getenv("COUCHBASE_USERNAME"); - public static final String COUCHBASE_PASSWORD = System.getenv("COUCHBASE_PASSWORD"); - public static final String COUCHBASE_BUCKET_NAME = System.getenv("COUCHBASE_BUCKET_NAME"); + public static final String REDIS_URL = System.getenv("REDIS_URL"); public static final String TELEGRAM_BOT_TOKEN = System.getenv("TELEGRAM_BOT_TOKEN"); public static final String TELEGRAM_BOT_USERNAME = System.getenv("TELEGRAM_BOT_USERNAME"); diff --git a/src/main/java/com/miti99/storescraperbot/constant/Constant.java b/src/main/java/com/miti99/storescraperbot/constant/Constant.java new file mode 100644 index 0000000..4a7fee3 --- /dev/null +++ b/src/main/java/com/miti99/storescraperbot/constant/Constant.java @@ -0,0 +1,5 @@ +package com.miti99.storescraperbot.constant; + +public class Constant { + public static final String APP_NAME = "store_scraper_bot"; +} diff --git a/src/main/java/com/miti99/storescraperbot/model/AbstractModel.java b/src/main/java/com/miti99/storescraperbot/model/AbstractModel.java index 44b3586..6659b30 100644 --- a/src/main/java/com/miti99/storescraperbot/model/AbstractModel.java +++ b/src/main/java/com/miti99/storescraperbot/model/AbstractModel.java @@ -1,11 +1,14 @@ package com.miti99.storescraperbot.model; -import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.gson.annotations.SerializedName; import lombok.Getter; +import lombok.RequiredArgsConstructor; @Getter +@RequiredArgsConstructor public abstract class AbstractModel { + final K key; - @JsonProperty("class") + @SerializedName("class") protected String clazz = getClass().getSimpleName(); } diff --git a/src/main/java/com/miti99/storescraperbot/model/Admin.java b/src/main/java/com/miti99/storescraperbot/model/Admin.java index fec1850..49fd54b 100644 --- a/src/main/java/com/miti99/storescraperbot/model/Admin.java +++ b/src/main/java/com/miti99/storescraperbot/model/Admin.java @@ -10,4 +10,8 @@ import lombok.Setter; @Setter public class Admin extends AbstractModel { List groups = new ArrayList<>(); + + public Admin(String key) { + super(key); + } } diff --git a/src/main/java/com/miti99/storescraperbot/model/AppleApp.java b/src/main/java/com/miti99/storescraperbot/model/AppleApp.java index cedeb03..3463b99 100644 --- a/src/main/java/com/miti99/storescraperbot/model/AppleApp.java +++ b/src/main/java/com/miti99/storescraperbot/model/AppleApp.java @@ -9,4 +9,8 @@ import lombok.Setter; public class AppleApp extends AbstractModel { long cacheTime; AppleAppResponse rawResponse; + + public AppleApp(String key) { + super(key); + } } diff --git a/src/main/java/com/miti99/storescraperbot/model/GoogleApp.java b/src/main/java/com/miti99/storescraperbot/model/GoogleApp.java index e18f7dd..a6d7903 100644 --- a/src/main/java/com/miti99/storescraperbot/model/GoogleApp.java +++ b/src/main/java/com/miti99/storescraperbot/model/GoogleApp.java @@ -9,4 +9,8 @@ import lombok.Setter; public class GoogleApp extends AbstractModel { long cacheTime; GoogleAppResponse rawResponse; + + public GoogleApp(String key) { + super(key); + } } diff --git a/src/main/java/com/miti99/storescraperbot/model/Group.java b/src/main/java/com/miti99/storescraperbot/model/Group.java index 70edef3..609aea5 100644 --- a/src/main/java/com/miti99/storescraperbot/model/Group.java +++ b/src/main/java/com/miti99/storescraperbot/model/Group.java @@ -11,6 +11,10 @@ import lombok.Setter; public class Group extends AbstractModel { List apps; + public Group(Long key) { + super(key); + } + public static class App { String appId; AppType type; diff --git a/src/main/java/com/miti99/storescraperbot/repository/AbstractRepository.java b/src/main/java/com/miti99/storescraperbot/repository/AbstractRepository.java index adffca0..5be7b34 100644 --- a/src/main/java/com/miti99/storescraperbot/repository/AbstractRepository.java +++ b/src/main/java/com/miti99/storescraperbot/repository/AbstractRepository.java @@ -1,29 +1,32 @@ package com.miti99.storescraperbot.repository; -import com.couchbase.client.java.Collection; +import com.google.common.base.CaseFormat; import com.miti99.storescraperbot.config.Config; +import com.miti99.storescraperbot.constant.Constant; import com.miti99.storescraperbot.model.AbstractModel; -import com.miti99.storescraperbot.util.CouchbaseUtil; +import com.miti99.storescraperbot.util.GsonUtil; +import com.miti99.storescraperbot.util.RedisUtil; import java.lang.reflect.ParameterizedType; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; import lombok.extern.log4j.Log4j2; -/** 1 repository = 1 collection */ @Log4j2 +@NoArgsConstructor(access = AccessLevel.PROTECTED) public abstract class AbstractRepository> { - public static final String SEPARATOR = "_"; - // protected static ObjectMapper objectMapper = new ObjectMapper(); + public static final String SEPARATOR = ":"; + protected final Class classK = getKeyClass(); protected final Class classV = getDataClass(); - // protected final JavaType type = objectMapper.getTypeFactory().constructType(classV); - protected final String scopeName = Config.ENV.name().toLowerCase(); - protected final String collectionName; + protected final String prefix = + String.join( + SEPARATOR, + Constant.APP_NAME, + Config.ENV.name().toLowerCase(), + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, classV.getSimpleName())); - protected AbstractRepository(String collectionName) { - this.collectionName = collectionName.toLowerCase(); - CouchbaseUtil.createCollection(scopeName, collectionName); - } - - public Collection collection() { - return CouchbaseUtil.BUCKET.scope(scopeName).collection(collectionName); + protected Class getKeyClass() { + return (Class) + ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; } /** @@ -43,7 +46,7 @@ public abstract class AbstractRepository> { if (exist(key)) { return; } - V data = classV.getDeclaredConstructor().newInstance(); + V data = classV.getDeclaredConstructor(classK).newInstance(key); save(key, data); } catch (Exception e) { log.error("Error while initializing data", e); @@ -51,13 +54,14 @@ public abstract class AbstractRepository> { } protected String getDatabaseKey(K key) { - return String.join(SEPARATOR, classV.getSimpleName(), String.valueOf(key)); + return String.join(SEPARATOR, prefix, String.valueOf(key)); } public void save(K key, V data) { var databaseKey = getDatabaseKey(key); - try { - collection().upsert(databaseKey, data); + try (var jedis = RedisUtil.getJedis()) { + var json = GsonUtil.toJson(data); + jedis.set(databaseKey, json); } catch (Exception e) { log.error("save error - key {}, databaseKey {}", key, databaseKey, e); } @@ -65,8 +69,8 @@ public abstract class AbstractRepository> { public boolean exist(K key) { var databaseKey = getDatabaseKey(key); - try { - return collection().exists(databaseKey).exists(); + try (var jedis = RedisUtil.getJedis()) { + return jedis.exists(databaseKey); } catch (Exception e) { log.error("exist error - key {}, databaseKey {}", key, databaseKey, e); return false; @@ -75,12 +79,9 @@ public abstract class AbstractRepository> { public V load(K key) { var databaseKey = getDatabaseKey(key); - try { - var getResult = collection().get(databaseKey); - if (getResult == null) { - return null; - } - return getResult.contentAs(classV); + try (var jedis = RedisUtil.getJedis()) { + var json = jedis.get(databaseKey); + return GsonUtil.fromJson(json, classV); } catch (Exception e) { log.error("load error - key {}, databaseKey {}", key, databaseKey, e); return null; @@ -89,8 +90,8 @@ public abstract class AbstractRepository> { public void delete(K key) { var databaseKey = getDatabaseKey(key); - try { - collection().remove(databaseKey); + try (var jedis = RedisUtil.getJedis()) { + jedis.del(databaseKey); } catch (Exception e) { log.error("delete error", e); } diff --git a/src/main/java/com/miti99/storescraperbot/repository/AdminRepository.java b/src/main/java/com/miti99/storescraperbot/repository/AdminRepository.java index 03f447f..4f29514 100644 --- a/src/main/java/com/miti99/storescraperbot/repository/AdminRepository.java +++ b/src/main/java/com/miti99/storescraperbot/repository/AdminRepository.java @@ -2,14 +2,12 @@ package com.miti99.storescraperbot.repository; import com.miti99.storescraperbot.model.Admin; -/** - * Đây là repository chỉ chứa 1 key duy nhất, key là "" (rỗng) - */ +/** Đây là repository chỉ chứa 1 key duy nhất, key là "" (rỗng) */ public class AdminRepository extends AbstractRepository { public static final AdminRepository INSTANCE = new AdminRepository(); protected AdminRepository() { - super("admin"); + super(); } public void init() { diff --git a/src/main/java/com/miti99/storescraperbot/repository/AppleAppRepository.java b/src/main/java/com/miti99/storescraperbot/repository/AppleAppRepository.java index 913594b..d8b0ae4 100644 --- a/src/main/java/com/miti99/storescraperbot/repository/AppleAppRepository.java +++ b/src/main/java/com/miti99/storescraperbot/repository/AppleAppRepository.java @@ -1,12 +1,7 @@ package com.miti99.storescraperbot.repository; import com.miti99.storescraperbot.model.AppleApp; -import com.miti99.storescraperbot.model.Group; public class AppleAppRepository extends AbstractRepository { public static final AppleAppRepository INSTANCE = new AppleAppRepository(); - - protected AppleAppRepository() { - super("apple"); - } } diff --git a/src/main/java/com/miti99/storescraperbot/repository/GoogleAppRepository.java b/src/main/java/com/miti99/storescraperbot/repository/GoogleAppRepository.java index 2a4eaf4..8c2186f 100644 --- a/src/main/java/com/miti99/storescraperbot/repository/GoogleAppRepository.java +++ b/src/main/java/com/miti99/storescraperbot/repository/GoogleAppRepository.java @@ -1,12 +1,7 @@ package com.miti99.storescraperbot.repository; import com.miti99.storescraperbot.model.GoogleApp; -import com.miti99.storescraperbot.model.Group; public class GoogleAppRepository extends AbstractRepository { private static final GoogleAppRepository INSTANCE = new GoogleAppRepository(); - - protected GoogleAppRepository() { - super("google"); - } } diff --git a/src/main/java/com/miti99/storescraperbot/repository/GroupRepository.java b/src/main/java/com/miti99/storescraperbot/repository/GroupRepository.java index d72efde..a47798e 100644 --- a/src/main/java/com/miti99/storescraperbot/repository/GroupRepository.java +++ b/src/main/java/com/miti99/storescraperbot/repository/GroupRepository.java @@ -4,8 +4,4 @@ import com.miti99.storescraperbot.model.Group; public class GroupRepository extends AbstractRepository { public static final GroupRepository INSTANCE = new GroupRepository(); - - protected GroupRepository() { - super("group"); - } } diff --git a/src/main/java/com/miti99/storescraperbot/util/CouchbaseUtil.java b/src/main/java/com/miti99/storescraperbot/util/CouchbaseUtil.java deleted file mode 100644 index 20487f6..0000000 --- a/src/main/java/com/miti99/storescraperbot/util/CouchbaseUtil.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.miti99.storescraperbot.util; - -import static com.miti99.storescraperbot.config.Config.COUCHBASE_BUCKET_NAME; -import static com.miti99.storescraperbot.config.Config.COUCHBASE_CONNECTION_STRING; -import static com.miti99.storescraperbot.config.Config.COUCHBASE_PASSWORD; -import static com.miti99.storescraperbot.config.Config.COUCHBASE_USERNAME; - -import com.couchbase.client.java.Bucket; -import com.couchbase.client.java.Cluster; -import com.couchbase.client.java.ClusterOptions; -import com.couchbase.client.java.manager.collection.CollectionSpec; -import com.miti99.storescraperbot.config.Config; -import java.time.Duration; -import lombok.extern.log4j.Log4j2; - -@Log4j2 -public class CouchbaseUtil { - public static final Cluster CLUSTER; - public static final Bucket BUCKET; - - static { - CLUSTER = - Cluster.connect( - COUCHBASE_CONNECTION_STRING, - ClusterOptions.clusterOptions(COUCHBASE_USERNAME, COUCHBASE_PASSWORD) - .environment(env -> {})); - - BUCKET = CLUSTER.bucket(COUCHBASE_BUCKET_NAME); - BUCKET.waitUntilReady(Duration.ofSeconds(10)); - } - - public static void createScope(String scopeName) { - var collectionManager = BUCKET.collections(); - try { - boolean scopeExists = - collectionManager.getAllScopes().stream().anyMatch(s -> s.name().equals(scopeName)); - - if (!scopeExists) { - collectionManager.createScope(scopeName); - log.info("Scope created: {}", scopeName); - } else { - log.info("Scope existed: {}", scopeName); - } - } catch (Exception e) { - log.error("createScope error - scopeName: '{}'", scopeName, e); - } - } - - public static void createCollection(String scopeName, String collectionName) { - var collectionManager = BUCKET.collections(); - try { - var scopeSpecOpt = - collectionManager.getAllScopes().stream() - .filter(s -> s.name().equals(scopeName)) - .findFirst(); - if (scopeSpecOpt.isEmpty()) { - createScope(scopeName); - createCollection(scopeName, collectionName); - return; - } - - var scopeSpec = scopeSpecOpt.get(); - boolean collectionExists = - scopeSpec.collections().stream().anyMatch(c -> c.name().equals(collectionName)); - - if (!collectionExists) { - var spec = CollectionSpec.create(collectionName, scopeName); - collectionManager.createCollection(spec); - log.info("Collection created: {} in {}", collectionName, scopeName); - } else { - log.info("Collection existed: {} in {}", collectionName, scopeName); - } - } catch (Exception e) { - log.error( - "createCollection error - collectionName: '{}', scopeName: '{}'", - collectionName, - scopeName, - e); - } - } -} diff --git a/src/main/java/com/miti99/storescraperbot/util/GsonUtil.java b/src/main/java/com/miti99/storescraperbot/util/GsonUtil.java new file mode 100644 index 0000000..d8e5718 --- /dev/null +++ b/src/main/java/com/miti99/storescraperbot/util/GsonUtil.java @@ -0,0 +1,18 @@ +package com.miti99.storescraperbot.util; + +import com.google.gson.Gson; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class GsonUtil { + public static final Gson GSON = new Gson(); + + public static T fromJson(String input, Class valueType) { + return GSON.fromJson(input, valueType); + } + + public static String toJson(Object input) { + return GSON.toJson(input); + } +} diff --git a/src/main/java/com/miti99/storescraperbot/util/JacksonUtil.java b/src/main/java/com/miti99/storescraperbot/util/JacksonUtil.java deleted file mode 100644 index de46f13..0000000 --- a/src/main/java/com/miti99/storescraperbot/util/JacksonUtil.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.miti99.storescraperbot.util; - -import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.PropertyAccessor; -import com.fasterxml.jackson.core.JsonParser.Feature; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import lombok.SneakyThrows; - -public class JacksonUtil { - public static ObjectMapper MAPPER = objectMapper(); - - private static ObjectMapper objectMapper() { - var objectMapper = new ObjectMapper(); - - objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); - objectMapper.disable( - SerializationFeature.FAIL_ON_EMPTY_BEANS, - SerializationFeature.INDENT_OUTPUT, - SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); - - objectMapper.enable( - DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, - DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, - DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL); - objectMapper.enable( - Feature.ALLOW_SINGLE_QUOTES, Feature.ALLOW_UNQUOTED_FIELD_NAMES, Feature.IGNORE_UNDEFINED); - objectMapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING); - - objectMapper.setSerializationInclusion(Include.NON_NULL); - objectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY); - - return objectMapper; - } - - @SneakyThrows - public static T readValue(String input, Class valueType) { - return MAPPER.readValue(input, valueType); - } - - @SneakyThrows - public static String writeValueAsString(Object input) { - return MAPPER.writeValueAsString(input); - } -} diff --git a/src/main/java/com/miti99/storescraperbot/util/RedisUtil.java b/src/main/java/com/miti99/storescraperbot/util/RedisUtil.java new file mode 100644 index 0000000..78143cc --- /dev/null +++ b/src/main/java/com/miti99/storescraperbot/util/RedisUtil.java @@ -0,0 +1,17 @@ +package com.miti99.storescraperbot.util; + +import static com.miti99.storescraperbot.config.Config.REDIS_URL; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class RedisUtil { + private static final JedisPool REDIS_POOL = new JedisPool(REDIS_URL); + + public static Jedis getJedis() { + return REDIS_POOL.getResource(); + } +} diff --git a/src/test/java/com/miti99/storescraperbot/api/apple/AppStoreScraperTest.java b/src/test/java/com/miti99/storescraperbot/api/apple/AppStoreScraperTest.java index 9a32b53..931b9a5 100644 --- a/src/test/java/com/miti99/storescraperbot/api/apple/AppStoreScraperTest.java +++ b/src/test/java/com/miti99/storescraperbot/api/apple/AppStoreScraperTest.java @@ -1,9 +1,7 @@ package com.miti99.storescraperbot.api.apple; -import static org.junit.jupiter.api.Assertions.*; - import com.miti99.storescraperbot.api.apple.request.AppleAppRequest; -import com.miti99.storescraperbot.util.JacksonUtil; +import com.miti99.storescraperbot.util.GsonUtil; import org.junit.jupiter.api.Test; class AppStoreScraperTest { @@ -11,6 +9,6 @@ class AppStoreScraperTest { void testApp() { var request = new AppleAppRequest("com.mpt.kvtm"); var response = AppStoreScraper.app(request); - System.out.println(JacksonUtil.writeValueAsString(response)); + System.out.println(GsonUtil.toJson(response)); } } diff --git a/src/test/java/com/miti99/storescraperbot/api/google/GooglePlayScraperTest.java b/src/test/java/com/miti99/storescraperbot/api/google/GooglePlayScraperTest.java index e9da330..26cc8b9 100644 --- a/src/test/java/com/miti99/storescraperbot/api/google/GooglePlayScraperTest.java +++ b/src/test/java/com/miti99/storescraperbot/api/google/GooglePlayScraperTest.java @@ -1,9 +1,7 @@ package com.miti99.storescraperbot.api.google; -import static org.junit.jupiter.api.Assertions.*; - import com.miti99.storescraperbot.api.google.request.GoogleAppRequest; -import com.miti99.storescraperbot.util.JacksonUtil; +import com.miti99.storescraperbot.util.GsonUtil; import org.junit.jupiter.api.Test; class GooglePlayScraperTest { @@ -11,6 +9,6 @@ class GooglePlayScraperTest { void testApp() { var request = new GoogleAppRequest("vn.kvtm.js"); var response = GooglePlayScraper.app(request); - System.out.println(JacksonUtil.writeValueAsString(response)); + System.out.println(GsonUtil.toJson(response)); } }