Skip to content

Commit

Permalink
Setup Cache & Apply Cache to Cluster, Table (#27)
Browse files Browse the repository at this point in the history
* Setup Cache

* Add Cache to Retrieve Cluster & Table
  • Loading branch information
seungh0 authored Jul 4, 2024
1 parent 05e9dbf commit 74e0d82
Show file tree
Hide file tree
Showing 9 changed files with 236 additions and 61 deletions.
9 changes: 7 additions & 2 deletions cadio-core/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
dependencies {
// Spring Boot
implementation("org.springframework.boot:spring-boot-starter")
implementation("org.springframework.boot:spring-boot-starter-json")

//TODO ClusterFactory 만들어지면 변경
api("com.datastax.oss:java-driver-core:${datastaxJavaDriverVersion}")
Expand All @@ -11,12 +10,18 @@ dependencies {
// implementation("com.datastax.oss:java-driver-query-builder:${datastaxJavaDriverVersion}")
// implementation("com.datastax.oss:java-driver-mapper-runtime:${datastaxJavaDriverVersion}")

api("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.1")
// Json
implementation("org.springframework.boot:spring-boot-starter-json")
implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.1")

// CommonsLang3
api("org.apache.commons:commons-lang3:3.13.0")
api("com.google.guava:guava:33.0.0-jre")
api("org.apache.commons:commons-collections4:4.4")

// Cache
implementation("org.springframework.boot:spring-boot-starter-cache")
implementation("com.github.ben-manes.caffeine:caffeine:3.1.8")
}

bootJar {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package kr.hakdang.cadio.core.support.cache;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.time.Duration;

/**
* CacheType
*
* @author seungh0
* @since 2024-07-04
*/
@Getter
public enum CacheType {

// TODO: 만료시간은 5분으로 가져가돼, N분마다 api를 쏴서 클러스터에 대한 정보를 갱신하는 것도 좋을듯
CLUSTER_LIST(CacheTypeNames.CLUSTER_LIST, Duration.ofMinutes(5)),
CLUSTER(CacheTypeNames.CLUSTER, Duration.ofMinutes(5)),
TABLE_LIST(CacheTypeNames.TABLE_LIST, Duration.ofMinutes(5)),
TABLE(CacheTypeNames.TABLE, Duration.ofMinutes(5)),
;

private final String key;
private final Duration duration;

CacheType(String key, Duration duration) {
this.key = key;
this.duration = duration;
}

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public static class CacheTypeNames {

public static final String CLUSTER_LIST = "clusterList";
public static final String CLUSTER = "cluster";
public static final String TABLE_LIST = "tableList";
public static final String TABLE = "table";

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package kr.hakdang.cadio.core.support.cache;

import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
* LocalCacheConfig
*
* @author seungh0
* @since 2024-07-04
*/
@EnableCaching
@Configuration
public class LocalCacheConfig {

@Bean
public CacheManager cacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
List<CaffeineCache> caches = Arrays.stream(CacheType.values())
.map(cache -> new CaffeineCache(cache.getKey(), Caffeine.newBuilder()
.expireAfterWrite(cache.getDuration())
.build()
))
.collect(Collectors.toList());
cacheManager.setCaches(caches);
return cacheManager;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import kr.hakdang.cadio.common.model.Direction;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
Expand All @@ -14,6 +15,7 @@
* @since 2024-07-01
*/
@ToString
@EqualsAndHashCode
@Getter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class CursorRequest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,4 @@ public ApiResponse<ClusterNode> nodeDetail(
}
}


}
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
package kr.hakdang.cadio.web.route.cluster.keyspace;

import com.datastax.oss.driver.api.core.CqlSession;
import kr.hakdang.cadio.core.domain.cluster.TempClusterConnector;
import kr.hakdang.cadio.core.domain.cluster.keyspace.ClusterKeyspaceCommander;
import kr.hakdang.cadio.core.domain.cluster.keyspace.ClusterKeyspaceDescribeArgs;
import kr.hakdang.cadio.core.domain.cluster.keyspace.ClusterKeyspaceListResult;
import kr.hakdang.cadio.web.common.dto.response.ApiResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

Expand All @@ -26,46 +23,40 @@
@RequestMapping("/api/cassandra/cluster/{clusterId}")
public class ClusterKeyspaceApi {

private final TempClusterConnector tempClusterConnector;
private final ClusterKeyspaceCommander clusterKeyspaceCommander;
private final ClusterKeyspaceReader clusterKeyspaceReader;

public ClusterKeyspaceApi(
TempClusterConnector tempClusterConnector,
ClusterKeyspaceCommander clusterKeyspaceCommander
ClusterKeyspaceReader clusterKeyspaceReader
) {
this.tempClusterConnector = tempClusterConnector;
this.clusterKeyspaceCommander = clusterKeyspaceCommander;
this.clusterKeyspaceReader = clusterKeyspaceReader;
}

@GetMapping("/keyspace")
public ApiResponse<Map<String, Object>> keyspaceList(
@PathVariable String clusterId
) {
Map<String, Object> result = new HashMap<>();
try (CqlSession session = tempClusterConnector.makeSession(clusterId)) { //TODO : interface 작업할 때 facade layer 로 변경 예정
ClusterKeyspaceListResult result1 = clusterKeyspaceCommander.keyspaceList(session);

result.put("keyspaceList", result1.getKeyspaceList());
}

ClusterKeyspaceListResult response = clusterKeyspaceReader.listKeyspace(clusterId);
result.put("keyspaceList", response.getKeyspaceList());
return ApiResponse.ok(result);
}

@PutMapping("/keyspace/cache-evict")
public ApiResponse<Object> evictKeyspaceListCache(
@PathVariable String clusterId
) {
clusterKeyspaceReader.refreshKeyspaceCache(clusterId);
return ApiResponse.OK;
}

@GetMapping("/keyspace/{keyspace}")
public Map<String, Object> keyspaceDetail(
@PathVariable String clusterId,
@PathVariable String keyspace
) {
Map<String, Object> result = new HashMap<>();
try (CqlSession session = tempClusterConnector.makeSession(clusterId)) { //TODO : interface 작업할 때 facade layer 로 변경 예정
result.put("describe", clusterKeyspaceCommander.describe(session, ClusterKeyspaceDescribeArgs.builder()
.keyspace(keyspace)
.withChildren(false)
.pretty(true)
.build()));

}

String keyspaceDescribe = clusterKeyspaceReader.getKeyspace(clusterId, keyspace);
result.put("describe", keyspaceDescribe);
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package kr.hakdang.cadio.web.route.cluster.keyspace;

import com.datastax.oss.driver.api.core.CqlSession;
import kr.hakdang.cadio.core.domain.cluster.TempClusterConnector;
import kr.hakdang.cadio.core.domain.cluster.keyspace.ClusterKeyspaceCommander;
import kr.hakdang.cadio.core.domain.cluster.keyspace.ClusterKeyspaceDescribeArgs;
import kr.hakdang.cadio.core.domain.cluster.keyspace.ClusterKeyspaceListResult;
import kr.hakdang.cadio.core.support.cache.CacheType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

/**
* ClusterKeyspaceReader
*
* @author seungh0
* @since 2024-07-04
*/
@Slf4j
@Service
public class ClusterKeyspaceReader {

private final TempClusterConnector tempClusterConnector;
private final ClusterKeyspaceCommander clusterKeyspaceCommander;

public ClusterKeyspaceReader(
TempClusterConnector tempClusterConnector,
ClusterKeyspaceCommander clusterKeyspaceCommander
) {
this.tempClusterConnector = tempClusterConnector;
this.clusterKeyspaceCommander = clusterKeyspaceCommander;
}

@Cacheable(value = CacheType.CacheTypeNames.CLUSTER_LIST)
public ClusterKeyspaceListResult listKeyspace(String clusterId) {
try (CqlSession session = tempClusterConnector.makeSession(clusterId)) {
return clusterKeyspaceCommander.keyspaceList(session);
}
}

@CacheEvict(value = CacheType.CacheTypeNames.CLUSTER_LIST)
public void refreshKeyspaceCache(String clusterId) {
log.info("ClusterList ({}) is evicted", clusterId);
}

@Cacheable(value = CacheType.CacheTypeNames.CLUSTER_LIST)
public String getKeyspace(String clusterId, String keyspace) {
try (CqlSession session = tempClusterConnector.makeSession(clusterId)) {
return clusterKeyspaceCommander.describe(session, ClusterKeyspaceDescribeArgs.builder()
.keyspace(keyspace)
.withChildren(false)
.pretty(true)
.build());
}
}

}
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
package kr.hakdang.cadio.web.route.cluster.table;

import com.datastax.oss.driver.api.core.CqlSession;
import jakarta.validation.Valid;
import kr.hakdang.cadio.core.domain.cluster.TempClusterConnector;
import kr.hakdang.cadio.core.domain.cluster.keyspace.table.ClusterTable;
import kr.hakdang.cadio.core.domain.cluster.keyspace.table.ClusterTableArgs;
import kr.hakdang.cadio.core.domain.cluster.keyspace.table.ClusterTableArgs.ClusterTableGetArgs;
import kr.hakdang.cadio.core.domain.cluster.keyspace.table.ClusterTableGetCommander;
import kr.hakdang.cadio.core.domain.cluster.keyspace.table.ClusterTableGetResult;
import kr.hakdang.cadio.core.domain.cluster.keyspace.table.ClusterTableListCommander;
import kr.hakdang.cadio.core.domain.cluster.keyspace.table.ClusterTableListResult;
import kr.hakdang.cadio.web.common.dto.request.CursorRequest;
import kr.hakdang.cadio.web.common.dto.response.ApiResponse;
import kr.hakdang.cadio.web.common.dto.response.CursorResponse;
import kr.hakdang.cadio.web.common.dto.response.ItemListWithCursorResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
Expand All @@ -30,18 +22,12 @@
@RequestMapping("/api/cassandra/cluster/{clusterId}/keyspace/{keyspace}")
public class ClusterTableApi {

private final TempClusterConnector tempClusterConnector;
private final ClusterTableListCommander clusterTableListCommander;
private final ClusterTableGetCommander clusterTableGetCommander;
private final ClusterTableReader clusterTableReader;

public ClusterTableApi(
TempClusterConnector tempClusterConnector,
ClusterTableListCommander clusterTableListCommander,
ClusterTableGetCommander clusterTableGetCommander
ClusterTableReader clusterTableReader
) {
this.tempClusterConnector = tempClusterConnector;
this.clusterTableListCommander = clusterTableListCommander;
this.clusterTableGetCommander = clusterTableGetCommander;
this.clusterTableReader = clusterTableReader;
}

@GetMapping("/table")
Expand All @@ -50,14 +36,8 @@ public ApiResponse<ItemListWithCursorResponse<ClusterTable, String>> listTables(
@PathVariable String keyspace,
@Valid CursorRequest cursorRequest
) {
try (CqlSession session = tempClusterConnector.makeSession(clusterId)) {
ClusterTableListResult result = clusterTableListCommander.listTables(session, ClusterTableArgs.ClusterTableListArgs.builder().build().builder()
.keyspace(keyspace)
.limit(cursorRequest.getSize())
.nextPageState(cursorRequest.getCursor())
.build());
return ApiResponse.ok(ItemListWithCursorResponse.of(result.getTables(), CursorResponse.withNext(result.getNextPageState())));
}
ItemListWithCursorResponse<ClusterTable, String> tables = clusterTableReader.listTables(clusterId, keyspace, cursorRequest);
return ApiResponse.ok(tables);
}

@GetMapping("/table/{table}")
Expand All @@ -67,14 +47,8 @@ public ApiResponse<ClusterTableGetResult> getTable(
@PathVariable String table,
@RequestParam(required = false, defaultValue = "false") boolean withTableDescribe
) {
try (CqlSession session = tempClusterConnector.makeSession(clusterId)) {
ClusterTableGetResult result = clusterTableGetCommander.getTable(session, ClusterTableGetArgs.builder()
.keyspace(keyspace)
.table(table)
.withTableDescribe(withTableDescribe)
.build());
return ApiResponse.ok(result);
}
ClusterTableGetResult cluster = clusterTableReader.getTable(clusterId, keyspace, table, withTableDescribe);
return ApiResponse.ok(cluster);
}

}
Loading

0 comments on commit 74e0d82

Please sign in to comment.