浏览代码

更新文件存储在本地磁盘的路径和通过 web 访问的 url

reghao 3 年之前
父节点
当前提交
83d03bacfc

+ 0 - 41
src/main/java/cn/reghao/tnb/file/app/config/ConfigMap.java

@@ -1,41 +0,0 @@
-package cn.reghao.tnb.file.app.config;
-
-import cn.reghao.jutil.jdk.machine.data.detail.DiskDetail;
-import cn.reghao.tnb.file.app.util.LocalStore;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author reghao
- * @date 2022-03-22 16:49:08
- */
-@Deprecated
-public class ConfigMap {
-    public static String baseUrl;
-    private static final Map<String, DfsConfig> map = new HashMap<>();
-
-    public static void init(List<DfsConfig> list) {
-        list.forEach(dfsConfig -> {
-            String baseDir = dfsConfig.getBaseDir();
-            map.putIfAbsent(baseDir, dfsConfig);
-        });
-    }
-
-    public static List<String> baseDirs() {
-        return new ArrayList<>(map.keySet());
-    }
-
-    public static PathUrl getPathUrl(String baseDir, String filePath) {
-        String relativePath = filePath.replace(baseDir, "");
-        DfsConfig dfsConfig = map.get(baseDir);
-        String group = dfsConfig.getGroup();
-        String node = dfsConfig.getNode();
-
-        String url = String.format("%s%s/%s/%s", baseUrl, group, node, relativePath);
-        String path = String.format("/%s/%s/%s", group, node, relativePath);
-        return new PathUrl(filePath, url, path);
-    }
-}

+ 0 - 35
src/main/java/cn/reghao/tnb/file/app/config/DfsConfig.java

@@ -1,35 +0,0 @@
-package cn.reghao.tnb.file.app.config;
-
-/**
- * @author reghao
- * @date 2022-03-22 16:35:28
- */
-public class DfsConfig {
-    private String baseDir;
-    private String group;
-    private String node;
-
-    public void setBaseDir(String baseDir) {
-        this.baseDir = baseDir;
-    }
-
-    public String getBaseDir() {
-        return baseDir;
-    }
-
-    public void setGroup(String group) {
-        this.group = group;
-    }
-
-    public String getGroup() {
-        return group;
-    }
-
-    public void setNode(String node) {
-        this.node = node;
-    }
-
-    public String getNode() {
-        return node;
-    }
-}

+ 5 - 5
src/main/java/cn/reghao/tnb/file/app/config/DfsProperties.java

@@ -13,7 +13,7 @@ import java.util.List;
 @ConfigurationProperties(prefix = "dfs")
 public class DfsProperties {
     private String domain;
-    private List<DfsConfig> dfsConfigs;
+    private List<String> baseDirs;
 
     public void setDomain(String domain) {
         this.domain = domain;
@@ -23,11 +23,11 @@ public class DfsProperties {
         return domain;
     }
 
-    public void setDfsConfigs(List<DfsConfig> dfsConfigs) {
-        this.dfsConfigs = dfsConfigs;
+    public void setBaseDirs(List<String> baseDirs) {
+        this.baseDirs = baseDirs;
     }
 
-    public List<DfsConfig> getDfsConfigs() {
-        return dfsConfigs;
+    public List<String> getBaseDirs() {
+        return baseDirs;
     }
 }

+ 2 - 2
src/main/java/cn/reghao/tnb/file/app/config/WebConfig.java

@@ -25,14 +25,14 @@ public class WebConfig extends WebMvcConfigurationSupport {
 
     @Override
     protected void addResourceHandlers(ResourceHandlerRegistry registry) {
-        List<DfsConfig> dfsConfigs = dfsProperties.getDfsConfigs();
+        /*List<DfsConfig> dfsConfigs = dfsProperties.getDfsConfigs();
         ConfigMap.baseUrl = String.format("//%s/", dfsProperties.getDomain());
         ConfigMap.init(dfsConfigs);
         dfsConfigs.forEach(dfsConfig -> {
             String resourceLocation = String.format("file:%s", dfsConfig.getBaseDir());
             String pathPattern = String.format("/%s/%s/**", dfsConfig.getGroup(), dfsConfig.getNode());
             registry.addResourceHandler(pathPattern).addResourceLocations(resourceLocation);
-        });
+        });*/
     }
 
     @Override

+ 0 - 35
src/main/java/cn/reghao/tnb/file/app/controller/ImageFileController.java

@@ -1,35 +0,0 @@
-package cn.reghao.tnb.file.app.controller;
-
-import cn.reghao.tnb.file.app.db.mapper.FileUrlMapper;
-import org.springframework.core.io.InputStreamResource;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.MediaType;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-
-import java.io.FileInputStream;
-
-/**
- * @author reghao
- * @date 2022-05-23 15:32:49
- */
-@RestController
-@RequestMapping("/image")
-public class ImageFileController {
-    private FileUrlMapper fileUrlMapper;
-
-    @GetMapping("/{uploadId}")
-    public ResponseEntity<InputStreamResource> videoPlayer(@PathVariable("uploadId") String uploadId) throws Exception {
-        //fileUrlMapper.findByUploadId(uploadId);
-        String filePath = "/home/reghao/Downloads/pic/10393c62.jpg";
-        FileInputStream fis = new FileInputStream(filePath);
-        InputStreamResource inputStreamResource = new InputStreamResource(fis);
-
-        HttpHeaders httpHeaders = new HttpHeaders();
-        httpHeaders.set("Pragma", "No-cache");
-        httpHeaders.set("Cache-Control", "no-cache");
-        return ResponseEntity.status(HttpStatus.OK).headers(httpHeaders).contentType(MediaType.IMAGE_JPEG)
-                .body(inputStreamResource);
-    }
-}

+ 23 - 2
src/main/java/cn/reghao/tnb/file/app/controller/VideoFileController.java

@@ -1,9 +1,16 @@
 package cn.reghao.tnb.file.app.controller;
 
 import cn.reghao.tnb.file.app.db.mapper.FileUrlMapper;
+import cn.reghao.tnb.file.app.model.dto.FileUrlDto;
+import org.springframework.core.io.InputStreamResource;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletResponse;
+import java.io.FileInputStream;
 import java.io.RandomAccessFile;
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
@@ -13,7 +20,7 @@ import java.util.Arrays;
  * @date 2022-04-24 16:13:10
  */
 @RestController
-@RequestMapping("/video")
+@RequestMapping
 public class VideoFileController {
     private final FileUrlMapper fileUrlMapper;
 
@@ -21,7 +28,7 @@ public class VideoFileController {
         this.fileUrlMapper = fileUrlMapper;
     }
 
-    @GetMapping("/playback")
+    @GetMapping("/video/playback")
     public void videoPlayer(@RequestParam("uploadId") String uploadId,
                             @RequestHeader(required = false) String range,
                             HttpServletResponse response) throws Exception {
@@ -56,4 +63,18 @@ public class VideoFileController {
         response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
         response.getOutputStream().write(Arrays.copyOf(bytes, readBytes));
     }
+
+    @GetMapping("/image/{uploadId}")
+    public ResponseEntity<InputStreamResource> videoPlayer(@PathVariable("uploadId") String uploadId) throws Exception {
+        FileUrlDto fileUrlDto = fileUrlMapper.findByUploadId(uploadId);
+        String filePath = fileUrlDto.getPath();
+        FileInputStream fis = new FileInputStream(filePath);
+        InputStreamResource inputStreamResource = new InputStreamResource(fis);
+
+        HttpHeaders httpHeaders = new HttpHeaders();
+        httpHeaders.set("Pragma", "No-cache");
+        httpHeaders.set("Cache-Control", "no-cache");
+        return ResponseEntity.status(HttpStatus.OK).headers(httpHeaders).contentType(MediaType.IMAGE_JPEG)
+                .body(inputStreamResource);
+    }
 }

+ 23 - 11
src/main/java/cn/reghao/tnb/file/app/service/FileUrlService.java

@@ -1,13 +1,12 @@
 package cn.reghao.tnb.file.app.service;
 
-import cn.reghao.tnb.file.app.config.ConfigMap;
+import cn.reghao.tnb.file.app.config.DfsProperties;
 import cn.reghao.tnb.file.app.config.PathUrl;
 import cn.reghao.tnb.file.app.util.LoadBalancer;
 import org.springframework.stereotype.Service;
 
 import java.io.IOException;
 import java.security.NoSuchAlgorithmException;
-import java.time.LocalDate;
 
 /**
  * @author reghao
@@ -15,24 +14,37 @@ import java.time.LocalDate;
  */
 @Service
 public class FileUrlService {
+    private final String domain;
     private final LoadBalancer loadBalancer;
     
-    public FileUrlService(LoadBalancer loadBalancer) {
+    public FileUrlService(LoadBalancer loadBalancer, DfsProperties dfsProperties) {
         this.loadBalancer = loadBalancer;
+        this.domain = dfsProperties.getDomain();
     }
 
     public PathUrl genPathAndUrl(String sha256sum, String fileId, String suffix) throws IOException, NoSuchAlgorithmException {
-        String baseDir = loadBalancer.getBaseDir(sha256sum);
-        String dateStr = LocalDate.now().toString().replace("-", "");
-        String filePath = String.format("%s%s/%s.%s", baseDir, dateStr, fileId, suffix);
-        return ConfigMap.getPathUrl(baseDir, filePath);
+        String storeDir = loadBalancer.getStoreDir(0, sha256sum);
+        String filePath = String.format("%s/%s.%s", storeDir, fileId, suffix);
+        String path = String.format("video/%s.%s", fileId, suffix);
+        String url = String.format("//%s/video/%s.%s", domain, fileId, suffix);
+        return new PathUrl(filePath, url, path);
+    }
+
+    public PathUrl genVideoPathAndUrl(String sha256sum, String uploadId, long fileSize, String fileId, String suffix)
+            throws IOException, NoSuchAlgorithmException {
+        String storeDir = loadBalancer.getStoreDir(fileSize, sha256sum);
+        String filePath = String.format("%s/%s.%s", storeDir, fileId, suffix);
+        String path = String.format("video/%s.%s", uploadId, suffix);
+        String url = String.format("//%s/video/%s.%s", domain, uploadId, suffix);
+        return new PathUrl(filePath, url, path);
     }
 
     public PathUrl getImagePathAndUrl(String sha256sum, String fileId, String suffix, int width, int height)
             throws IOException, NoSuchAlgorithmException {
-        String baseDir = loadBalancer.getBaseDir(sha256sum);
-        String dateStr = LocalDate.now().toString().replace("-", "");
-        String filePath = String.format("%s%s/%s_%sx%s.%s", baseDir, dateStr, fileId, width, height, suffix);
-        return ConfigMap.getPathUrl(baseDir, filePath);
+        String storeDir = loadBalancer.getStoreDir(0, sha256sum);
+        String filePath = String.format("%s/%s_%sx%s.%s", storeDir, fileId, width, height, suffix);
+        String path = String.format("video/%s.%s", fileId, suffix);
+        String url = String.format("//%s/image/%s.%s", domain, fileId, suffix);
+        return new PathUrl(filePath, url, path);
     }
 }

+ 8 - 5
src/main/java/cn/reghao/tnb/file/app/util/FileLifecycle.java

@@ -1,25 +1,28 @@
 package cn.reghao.tnb.file.app.util;
 
+import cn.reghao.tnb.file.app.config.DfsProperties;
 import org.springframework.beans.factory.DisposableBean;
 import org.springframework.boot.ApplicationArguments;
 import org.springframework.boot.ApplicationRunner;
 import org.springframework.stereotype.Component;
 
+import java.io.IOException;
+
 /**
  * @author reghao
  * @date 2022-03-23 09:22:01
  */
 @Component
 public class FileLifecycle implements ApplicationRunner, DisposableBean {
-    private final LoadBalancer loadBalancer;
+    private final DfsProperties dfsProperties;
 
-    public FileLifecycle(LoadBalancer loadBalancer) {
-        this.loadBalancer = loadBalancer;
+    public FileLifecycle(DfsProperties dfsProperties) {
+        this.dfsProperties = dfsProperties;
     }
 
     @Override
-    public void run(ApplicationArguments args) {
-        loadBalancer.init();
+    public void run(ApplicationArguments args) throws IOException {
+        LocalStores.init(dfsProperties);
     }
 
     @Override

+ 0 - 15
src/main/java/cn/reghao/tnb/file/app/util/LoadBalancer.java

@@ -1,7 +1,6 @@
 package cn.reghao.tnb.file.app.util;
 
 import cn.reghao.jutil.jdk.security.DigestUtil;
-import cn.reghao.tnb.file.app.config.ConfigMap;
 import com.google.common.hash.HashFunction;
 import com.google.common.hash.Hashing;
 import org.springframework.stereotype.Component;
@@ -18,22 +17,8 @@ import java.util.*;
  */
 @Component
 public class LoadBalancer {
-    @Deprecated
-    private final List<String> nodes = new ArrayList<>();
     private final HashFunction hashFunction = Hashing.murmur3_32_fixed();
 
-    @Deprecated
-    public void init() {
-        nodes.addAll(ConfigMap.baseDirs());
-    }
-
-    @Deprecated
-    public String getBaseDir(Object object) throws IOException, NoSuchAlgorithmException {
-        int hash = hash(object);
-        int nodeIdx = hash % nodes.size();
-        return nodes.get(nodeIdx);
-    }
-
     public String getStoreDir(long fileSize, String sha256sum) throws IOException, NoSuchAlgorithmException {
         String store = LocalStores.getMaxStore(fileSize);
         List<String> subDirs = LocalStores.getSubDirs(store);

+ 7 - 1
src/main/java/cn/reghao/tnb/file/app/util/LocalStore.java

@@ -41,9 +41,14 @@ public class LocalStore {
         return total - fileStore.getUsableSpace() + len > max;
     }
 
+    public long availableSize(long len) throws IOException {
+        return total - fileStore.getUsableSpace() + len;
+    }
+
     @Override
     public int hashCode() {
         int result = 17;
+        result = result * 31 + blockId.hashCode();
         result = result * 31 + fs.hashCode();
         result = result * 31 + fsType.hashCode();
         result = result * 31 + mountedOn.hashCode();
@@ -58,7 +63,8 @@ public class LocalStore {
 
         if (other instanceof LocalStore) {
             LocalStore o = (LocalStore) other;
-            return o.fs.equals(fs) && o.fsType.equals(fsType) && o.mountedOn.equals(mountedOn);
+            return o.blockId.equals(blockId) && o.fs.equals(fs)
+                    && o.fsType.equals(fsType) && o.mountedOn.equals(mountedOn);
         } else {
             return false;
         }

+ 22 - 5
src/main/java/cn/reghao/tnb/file/app/util/LocalStores.java

@@ -1,6 +1,5 @@
 package cn.reghao.tnb.file.app.util;
 
-import cn.reghao.tnb.file.app.config.DfsConfig;
 import cn.reghao.tnb.file.app.config.DfsProperties;
 import org.apache.commons.io.FileUtils;
 
@@ -17,14 +16,15 @@ import java.util.*;
  * @date 2022-05-23 18:21:22
  */
 public class LocalStores {
+    private static String domain;
     private static final Map<String, LocalStore> storeMap = new HashMap<>();
     private static final Map<String, List<String>> subDirs = new HashMap<>();
 
     public static void init(DfsProperties dfsProperties) throws IOException {
+        domain = dfsProperties.getDomain();
         Map<String, String> blockIdMap = getBlockIdMap();
         Map<String, String> checker = new HashMap<>();
-        for (DfsConfig dfsConfig : dfsProperties.getDfsConfigs()) {
-            String baseDir = dfsConfig.getBaseDir();
+        for (String baseDir : dfsProperties.getBaseDirs()) {
             FileStore fileStore = Files.getFileStore(Path.of(baseDir));
             String fs = fileStore.name();
             String previous = checker.putIfAbsent(fs, baseDir);
@@ -71,9 +71,26 @@ public class LocalStores {
         }
     }
 
+    // TODO 优化算法, 处理异常
     public static String getMaxStore(long size) {
-        String storePath = storeMap.keySet().iterator().next();
-        return storePath;
+        Map<String, Long> map = new HashMap<>();
+        for (Map.Entry<String, LocalStore> entry : storeMap.entrySet()) {
+            String storePath = entry.getKey();
+            long availSize = 0L;
+            try {
+                LocalStore localStore = entry.getValue();
+                availSize = localStore.availableSize(size);
+            } catch (IOException ignored) {
+            } finally {
+                map.put(storePath, availSize);
+            }
+        }
+
+        List<String> result = new ArrayList<>();
+        map.entrySet().stream()
+                .sorted(Map.Entry.comparingByValue())
+                .forEachOrdered(b -> result.add(b.getKey()));
+        return result.get(result.size()-1);
     }
 
     public static List<String> getSubDirs(String store) {

+ 3 - 10
src/main/resources/application-dev.yml

@@ -13,13 +13,6 @@ dubbo:
     address: zookeeper://localhost:2181
 dfs:
   domain: file.reghao.cn
-  dfsConfigs:
-    - baseDir: /home/reghao/opt/file/group0/
-      group: group0
-      node: node0
-    - baseDir: /home/reghao/mnt/file/
-      group: group1
-      node: node0
-#    - baseDir: /home/reghao/opt/file/group2/
-#      group: group2
-#      node: node0
+  baseDirs:
+    - /home/reghao/opt/file/group0/
+    - /home/reghao/mnt/file/

+ 1 - 1
src/test/java/FileTest.java

@@ -82,7 +82,7 @@ public class FileTest {
             FileInputStream fis = new FileInputStream(file);
             String sha256sum = DigestUtil.sha256sum(fis);
             String storeDir = loadBalancer.getStoreDir(len, sha256sum);
-            System.out.println();
+            System.out.println(storeDir);
         }
     }
 }