RedisResource.java 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. package org.ssssssss.magicapi.adapter.resource;
  2. import org.slf4j.Logger;
  3. import org.slf4j.LoggerFactory;
  4. import org.springframework.data.redis.core.Cursor;
  5. import org.springframework.data.redis.core.RedisCallback;
  6. import org.springframework.data.redis.core.ScanOptions;
  7. import org.springframework.data.redis.core.StringRedisTemplate;
  8. import org.ssssssss.magicapi.adapter.Resource;
  9. import java.io.IOException;
  10. import java.nio.charset.StandardCharsets;
  11. import java.util.*;
  12. import java.util.concurrent.ConcurrentHashMap;
  13. import java.util.function.Function;
  14. public class RedisResource extends KeyValueResource {
  15. private final StringRedisTemplate redisTemplate;
  16. private static final Logger logger = LoggerFactory.getLogger(RedisResource.class);
  17. private final Map<String, String> cachedContent = new ConcurrentHashMap<>();
  18. public RedisResource(StringRedisTemplate redisTemplate, String path, boolean readonly, RedisResource parent) {
  19. super(":", path, readonly, parent);
  20. this.redisTemplate = redisTemplate;
  21. }
  22. public RedisResource(StringRedisTemplate redisTemplate, String path, boolean readonly) {
  23. this(redisTemplate, path, readonly, null);
  24. }
  25. @Override
  26. public void readAll() {
  27. this.cachedContent.clear();
  28. List<String> keys = new ArrayList<>(keys());
  29. List<String> values = redisTemplate.opsForValue().multiGet(keys);
  30. if (values != null) {
  31. for (int i = 0, size = keys.size(); i < size; i++) {
  32. this.cachedContent.put(keys.get(i), values.get(i));
  33. }
  34. }
  35. }
  36. @Override
  37. public byte[] read() {
  38. String value = this.cachedContent.get(path);
  39. if (value == null) {
  40. value = redisTemplate.opsForValue().get(path);
  41. }
  42. return value == null ? new byte[0] : value.getBytes(StandardCharsets.UTF_8);
  43. }
  44. @Override
  45. public boolean write(String content) {
  46. this.redisTemplate.opsForValue().set(this.path, content);
  47. this.cachedContent.put(this.path, content);
  48. return true;
  49. }
  50. @Override
  51. protected boolean renameTo(Map<String, String> renameKeys) {
  52. renameKeys.forEach(this.redisTemplate::rename);
  53. renameKeys.forEach((oldKey, newKey) -> this.cachedContent.put(newKey, this.cachedContent.remove(oldKey)));
  54. return true;
  55. }
  56. @Override
  57. public boolean exists() {
  58. if (this.cachedContent.containsKey(this.path)) {
  59. return true;
  60. }
  61. return Boolean.TRUE.equals(this.redisTemplate.hasKey(this.path));
  62. }
  63. @Override
  64. protected boolean deleteByKey(String key) {
  65. if (Boolean.TRUE.equals(this.redisTemplate.delete(key))) {
  66. this.cachedContent.remove(key);
  67. return true;
  68. }
  69. return false;
  70. }
  71. @Override
  72. protected Function<String, Resource> mappedFunction() {
  73. return (it) -> new RedisResource(this.redisTemplate, it, readonly, this);
  74. }
  75. @Override
  76. protected Set<String> keys() {
  77. Set<String> keys = this.redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
  78. ScanOptions options = new ScanOptions.ScanOptionsBuilder()
  79. .count(Long.MAX_VALUE)
  80. .match((isDirectory() ? this.path : (this.path + separator)) + "*")
  81. .build();
  82. Set<String> returnKeys = new HashSet<>();
  83. try (Cursor<byte[]> cursor = connection.scan(options)) {
  84. while (cursor.hasNext()) {
  85. returnKeys.add(new String(cursor.next()));
  86. }
  87. } catch (IOException e) {
  88. logger.error("扫描key出错", e);
  89. }
  90. return returnKeys;
  91. });
  92. return keys == null ? Collections.emptySet() : keys;
  93. }
  94. @Override
  95. public String toString() {
  96. return String.format("redis://%s", getAbsolutePath());
  97. }
  98. }