From 615c614e11337403130b7d3c4b0feb5579fc2312 Mon Sep 17 00:00:00 2001 From: guqing <38999863+guqing@users.noreply.github.com> Date: Wed, 2 Mar 2022 18:06:54 +0800 Subject: [PATCH] Fix the problem jsonToCacheWrapper crashes when cache value is not JSON format (#1695) * fix: json to cache wrapper convertor when other exception * feat: Add test case for level cache --- .../app/cache/AbstractStringCacheStore.java | 5 +- .../halo/app/cache/LevelCacheStoreTest.java | 55 +++++++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 src/test/java/run/halo/app/cache/LevelCacheStoreTest.java diff --git a/src/main/java/run/halo/app/cache/AbstractStringCacheStore.java b/src/main/java/run/halo/app/cache/AbstractStringCacheStore.java index 3c870bc51d..c9c6f203f2 100644 --- a/src/main/java/run/halo/app/cache/AbstractStringCacheStore.java +++ b/src/main/java/run/halo/app/cache/AbstractStringCacheStore.java @@ -1,6 +1,7 @@ package run.halo.app.cache; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; import java.io.IOException; import java.util.Optional; import java.util.concurrent.TimeUnit; @@ -22,8 +23,8 @@ protected Optional> jsonToCacheWrapper(String json) { Assert.hasText(json, "json value must not be null"); CacheWrapper cacheWrapper = null; try { - cacheWrapper = JsonUtils.jsonToObject(json, CacheWrapper.class); - } catch (IOException e) { + cacheWrapper = JsonUtils.jsonToObject(json, new TypeReference<>() {}); + } catch (Exception e) { log.debug("Failed to convert json to wrapper value bytes: [{}]", json, e); } return Optional.ofNullable(cacheWrapper); diff --git a/src/test/java/run/halo/app/cache/LevelCacheStoreTest.java b/src/test/java/run/halo/app/cache/LevelCacheStoreTest.java new file mode 100644 index 0000000000..d269f7555e --- /dev/null +++ b/src/test/java/run/halo/app/cache/LevelCacheStoreTest.java @@ -0,0 +1,55 @@ +package run.halo.app.cache; + +import static org.assertj.core.api.Assertions.assertThat; +import static run.halo.app.model.support.HaloConst.FILE_SEPARATOR; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Optional; +import org.iq80.leveldb.DB; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.test.util.ReflectionTestUtils; +import run.halo.app.config.properties.HaloProperties; +import run.halo.app.utils.FileUtils; + +/** + * @author guqing + * @date 2022-03-02 + */ +public class LevelCacheStoreTest { + LevelCacheStore cacheStore; + HaloProperties haloProperties = new HaloProperties(); + + @BeforeEach + void setUp() throws IOException { + String testDir = FileUtils.createTempDirectory().toString(); + System.out.println(testDir); + haloProperties.setWorkDir(testDir + FILE_SEPARATOR); + cacheStore = new LevelCacheStore(haloProperties); + cacheStore.init(); + } + + @Test + public void corruptCacheStructureTest() { + cacheStore.put("A", "B"); + + // Simulate corrupt cache structure + DB levelDb = (DB) ReflectionTestUtils.getField(cacheStore, "LEVEL_DB"); + levelDb.put("B".getBytes(StandardCharsets.UTF_8), + "NOT_JSON".getBytes(StandardCharsets.UTF_8)); + + Optional bOpt = cacheStore.getAny("B", CacheWrapper.class); + assertThat(bOpt).isNotNull(); + assertThat(bOpt.isEmpty()).isTrue(); + + assertThat(cacheStore.toMap().toString()).isEqualTo("{A=B, B=null}"); + } + + @AfterEach + public void cleanUp() { + cacheStore.delete("A"); + cacheStore.delete("B"); + } +}