Browse Source

update dfs-store

reghao 3 years ago
parent
commit
bc08fc8a16
35 changed files with 416 additions and 174 deletions
  1. 39 0
      pom.xml
  2. 3 5
      src/main/java/cn/reghao/dfs/store/controller/MediaUploadController.java
  3. 13 0
      src/main/java/cn/reghao/dfs/store/db/mapper/ImageUrlMapper.java
  4. 1 8
      src/main/java/cn/reghao/dfs/store/db/mapper/VideoFileMapper.java
  5. 17 0
      src/main/java/cn/reghao/dfs/store/db/mapper/VideoUrlMapper.java
  6. 3 3
      src/main/java/cn/reghao/dfs/store/db/repository/FileRepository.java
  7. 8 0
      src/main/java/cn/reghao/dfs/store/model/constant/VideoResolution.java
  8. 1 2
      src/main/java/cn/reghao/dfs/store/model/dto/FileUrlDto.java
  9. 0 1
      src/main/java/cn/reghao/dfs/store/model/dto/PathUrl.java
  10. 2 0
      src/main/java/cn/reghao/dfs/store/model/po/FileInfo.java
  11. 3 3
      src/main/java/cn/reghao/dfs/store/model/po/FileUrl.java
  12. 2 12
      src/main/java/cn/reghao/dfs/store/model/po/ImageFile.java
  13. 22 0
      src/main/java/cn/reghao/dfs/store/model/po/ImageUrl.java
  14. 4 29
      src/main/java/cn/reghao/dfs/store/model/po/VideoFile.java
  15. 27 0
      src/main/java/cn/reghao/dfs/store/model/po/VideoUrl.java
  16. 3 2
      src/main/java/cn/reghao/dfs/store/model/vo/FilePartRet.java
  17. 11 0
      src/main/java/cn/reghao/dfs/store/model/vo/ImageFileRet.java
  18. 1 0
      src/main/java/cn/reghao/dfs/store/model/vo/UploadFileRet.java
  19. 10 6
      src/main/java/cn/reghao/dfs/store/model/vo/VideoFileRet.java
  20. 29 0
      src/main/java/cn/reghao/dfs/store/rpc/MediaUrlServiceImpl.java
  21. 6 4
      src/main/java/cn/reghao/dfs/store/service/FileUploadService.java
  22. 2 18
      src/main/java/cn/reghao/dfs/store/service/FileUrlService.java
  23. 22 1
      src/main/java/cn/reghao/dfs/store/service/media/ImageFileService.java
  24. 30 0
      src/main/java/cn/reghao/dfs/store/service/media/MediaQuality.java
  25. 43 23
      src/main/java/cn/reghao/dfs/store/service/media/VideoFileService.java
  26. 1 0
      src/main/java/cn/reghao/dfs/store/util/store/LocalStores.java
  27. 4 1
      src/main/resources/application-dev.yml
  28. 10 2
      src/main/resources/application.yml
  29. 2 10
      src/main/resources/mapper/FileInfoMapper.xml
  30. 4 4
      src/main/resources/mapper/FileUrlMapper.xml
  31. 4 16
      src/main/resources/mapper/ImageFileMapper.xml
  32. 23 0
      src/main/resources/mapper/ImageUrlMapper.xml
  33. 3 14
      src/main/resources/mapper/VideoFileMapper.xml
  34. 18 0
      src/main/resources/mapper/VideoUrlMapper.xml
  35. 45 10
      src/test/java/ConsistentCheckTest.java

+ 39 - 0
pom.xml

@@ -22,6 +22,13 @@
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
+            <dependency>
+                <groupId>org.springframework.cloud</groupId>
+                <artifactId>spring-cloud-dependencies</artifactId>
+                <version>Hoxton.SR10</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 
@@ -41,6 +48,11 @@
             <artifactId>web</artifactId>
             <version>1.0.0-SNAPSHOT</version>
         </dependency>
+        <dependency>
+            <groupId>cn.reghao.dfs</groupId>
+            <artifactId>dfs-api</artifactId>
+            <version>1.0.0-SNAPSHOT</version>
+        </dependency>
         <dependency>
             <groupId>cn.reghao.dfs</groupId>
             <artifactId>dfs-client</artifactId>
@@ -163,6 +175,33 @@
             <artifactId>activation</artifactId>
             <version>1.1.1</version>
         </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-spring-boot-starter</artifactId>
+            <version>2.7.8</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.apache.zookeeper</groupId>
+                    <artifactId>zookeeper</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.zookeeper</groupId>
+            <artifactId>zookeeper</artifactId>
+            <version>3.4.6</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-log4j12</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
     </dependencies>
 
     <profiles>

+ 3 - 5
src/main/java/cn/reghao/dfs/store/controller/MediaUploadController.java

@@ -71,15 +71,13 @@ public class MediaUploadController {
     public String uploadVideoFile(@Validated UploadFilePart uploadFilePart) throws Exception {
         FilePartRet filePartRet = fileUploadService.putFilePart(uploadFilePart);
         String uploadId = filePartRet.getUploadId();
+
         if (!filePartRet.isMerged()) {
             return WebBody.success(new VideoFileRet(uploadId));
         }
 
         PathUrl pathUrl = filePartRet.getPathUrl();
-        VideoFile videoFile = videoService.process(uploadId, pathUrl);
-        String videoUrl = videoFile.getBaseUrl();
-        String coverUrl = videoFile.getBaseCoverUrl();
-        Integer duration = videoFile.getDuration();
-        return WebBody.success(new VideoFileRet(uploadId, videoUrl, coverUrl, duration));
+        VideoFile videoFile = videoService.process(filePartRet.getFileId(), pathUrl);
+        return WebBody.success(new VideoFileRet(uploadId, videoFile));
     }
 }

+ 13 - 0
src/main/java/cn/reghao/dfs/store/db/mapper/ImageUrlMapper.java

@@ -0,0 +1,13 @@
+package cn.reghao.dfs.store.db.mapper;
+
+import cn.reghao.dfs.store.model.po.ImageUrl;
+import cn.reghao.jutil.jdk.db.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @author reghao
+ * @date 2022-08-05 11:21:11
+ */
+@Mapper
+public interface ImageUrlMapper extends BaseMapper<ImageUrl> {
+}

+ 1 - 8
src/main/java/cn/reghao/dfs/store/db/mapper/VideoFileMapper.java

@@ -5,18 +5,11 @@ import cn.reghao.dfs.store.model.po.VideoFile;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
-import java.util.List;
-
 /**
  * @author reghao
  * @date 2021-12-07 18:59:11
  */
 @Mapper
 public interface VideoFileMapper extends BaseMapper<VideoFile> {
-    void updateSetCover(@Param("fileId") String fileId, @Param("coverUrl") String coverUrl);
-    @Deprecated
-    void updateSetUrl(VideoFile videoFile);
-
-    VideoFile findByFileId(String fileId);
-    List<VideoFile> findByMatchBaseUrl(String pattern);
+    void updateSetCover(@Param("videoFileId") String videoFileId, @Param("coverUrl") String coverUrl);
 }

+ 17 - 0
src/main/java/cn/reghao/dfs/store/db/mapper/VideoUrlMapper.java

@@ -0,0 +1,17 @@
+package cn.reghao.dfs.store.db.mapper;
+
+import cn.reghao.dfs.api.dto.VideoUrlDto;
+import cn.reghao.dfs.store.model.po.VideoUrl;
+import cn.reghao.jutil.jdk.db.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2022-08-04 09:31:27
+ */
+@Mapper
+public interface VideoUrlMapper extends BaseMapper<VideoUrl> {
+    List<VideoUrlDto> findByVideoFileId(String videoFileId);
+}

+ 3 - 3
src/main/java/cn/reghao/dfs/store/db/repository/FileRepository.java

@@ -128,9 +128,9 @@ public class FileRepository {
     public void saveFile(String fileId, FileContentType fileContentType, PathUrl pathUrl) throws Exception {
         int fileType = fileContentType.getFileType();
         String contentType = fileContentType.getContentType();
-        String blockId = LocalStores.getBlockId(pathUrl.getAbsolutePath());
-        String relativePath = LocalStores.getRelativePath(pathUrl.getAbsolutePath());
-        FileUrl fileUrl = new FileUrl(fileId, blockId, relativePath, pathUrl.getUrl(), pathUrl.getPath());
+        String absolutePath = pathUrl.getAbsolutePath();
+        String blockId = LocalStores.getBlockId(absolutePath);
+        FileUrl fileUrl = new FileUrl(fileId, blockId, absolutePath, pathUrl.getUrl(), pathUrl.getPath());
 
         // TODO 文件上传完成后, 立即同步到其它节点
         // TODO 事务回滚时会在 FileStore 中产生碎片文件,即在数据库中找不到该文件的任何信息

+ 8 - 0
src/main/java/cn/reghao/dfs/store/model/constant/VideoResolution.java

@@ -0,0 +1,8 @@
+package cn.reghao.dfs.store.model.constant;
+
+/**
+ * @author reghao
+ * @date 2022-08-04 09:21:38
+ */
+public class VideoResolution {
+}

+ 1 - 2
src/main/java/cn/reghao/dfs/store/model/dto/FileUrlDto.java

@@ -14,8 +14,7 @@ public class FileUrlDto implements Serializable {
     private static final long serialVersionUID = 1L;
 
     private String fileId;
-    private String blockId;
-    private String relativePath;
+    private String absolutePath;
     private String filename;
     private String url;
     private String path;

+ 0 - 1
src/main/java/cn/reghao/dfs/store/model/dto/PathUrl.java

@@ -10,7 +10,6 @@ import lombok.Getter;
 @AllArgsConstructor
 @Getter
 public class PathUrl {
-    private String blockId;
     // 本地文件路径
     private String absolutePath;
     private String url;

+ 2 - 0
src/main/java/cn/reghao/dfs/store/model/po/FileInfo.java

@@ -25,6 +25,7 @@ public class FileInfo extends BaseObject<Integer> {
     // http content-type
     private String contentType;
     private Boolean uploaded;
+    private Boolean original;
 
     public FileInfo(String fileId, String sha256sum, String filename, long size,
                     FileContentType fileContentType, boolean uploaded) {
@@ -36,5 +37,6 @@ public class FileInfo extends BaseObject<Integer> {
         this.fileType = fileContentType.getFileType();
         this.contentType = fileContentType.getContentType();
         this.uploaded = uploaded;
+        this.original = true;
     }
 }

+ 3 - 3
src/main/java/cn/reghao/dfs/store/model/po/FileUrl.java

@@ -16,16 +16,16 @@ import lombok.Setter;
 public class FileUrl extends BaseObject<Integer> {
     private String fileId;
     private String blockId;
-    private String relativePath;
+    private String absolutePath;
     private String url;
     private String path;
     private int group;
     private int node;
 
-    public FileUrl(String fileId, String blockId, String relativePath, String url, String path) {
+    public FileUrl(String fileId, String blockId, String absolutePath, String url, String path) {
         this.fileId = fileId;
         this.blockId = blockId;
-        this.relativePath = relativePath;
+        this.absolutePath = absolutePath;
         this.url = url;
         this.path = path;
     }

+ 2 - 12
src/main/java/cn/reghao/dfs/store/model/po/ImageFile.java

@@ -18,16 +18,6 @@ import lombok.NoArgsConstructor;
 @EqualsAndHashCode(callSuper = true)
 @Data
 public class ImageFile extends BaseObject<Integer> {
-    //private String originFileId;
-    private String fileId;
-    private String baseUrl;
-    private Integer width;
-    private Integer height;
-
-    public ImageFile(SpiderImageFile spiderImageFile) {
-        this.fileId = spiderImageFile.getFileId();
-        this.baseUrl = spiderImageFile.getUrl();
-        this.width = spiderImageFile.getWidth();
-        this.height = spiderImageFile.getHeight();
-    }
+    private String imageFileId;
+    private Boolean horizontal;
 }

+ 22 - 0
src/main/java/cn/reghao/dfs/store/model/po/ImageUrl.java

@@ -0,0 +1,22 @@
+package cn.reghao.dfs.store.model.po;
+
+import cn.reghao.jutil.jdk.db.BaseObject;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author reghao
+ * @date 2022-08-05 11:21:23
+ */
+@AllArgsConstructor
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class ImageUrl extends BaseObject<Integer> {
+    private String imageFileId;
+    private String fileId;
+    private Integer width;
+    private Integer height;
+}

+ 4 - 29
src/main/java/cn/reghao/dfs/store/model/po/VideoFile.java

@@ -16,38 +16,13 @@ import lombok.Setter;
 @Setter
 @Getter
 public class VideoFile extends BaseObject<Integer> {
-    // TODO 后期提供一个 fileId List 表示其他分辨率的视频文件
-    //private String originFileId;
-    private String fileId;
-    private String coverFileId;
-    private Integer bandwidth;
-    private Double frameRate;
-    private Integer width;
-    private Integer height;
+    private String videoFileId;
     private Boolean horizontal;
-    private String rotate;
-    private String urlType;
-    private String baseUrl;
-    private String backupUrl;
     // 单位秒
     private Integer duration;
-    private String baseCoverUrl;
+    private String coverUrl;
 
-    public VideoFile(String fileId, String urlType, String baseUrl) {
-        this.fileId = fileId;
-        this.urlType = urlType;
-        this.baseUrl = baseUrl;
-    }
-
-    public VideoFile(SpiderVideoFile spiderVideoFile) {
-        this.fileId = spiderVideoFile.getVideoId();
-        this.frameRate = spiderVideoFile.getFrameRate();
-        this.width = spiderVideoFile.getWidth();
-        this.height = spiderVideoFile.getHeight();
-        this.horizontal = width > height;
-        this.urlType = spiderVideoFile.getUrlType();
-        this.baseUrl = spiderVideoFile.getVideoUrl();
-        this.duration = spiderVideoFile.getDuration();
-        this.baseCoverUrl = spiderVideoFile.getCoverUrl();
+    public VideoFile(String videoFileId) {
+        this.videoFileId = videoFileId;
     }
 }

+ 27 - 0
src/main/java/cn/reghao/dfs/store/model/po/VideoUrl.java

@@ -0,0 +1,27 @@
+package cn.reghao.dfs.store.model.po;
+
+import cn.reghao.jutil.jdk.db.BaseObject;
+
+/**
+ * @author reghao
+ * @date 2022-08-04 09:19:16
+ */
+public class VideoUrl extends BaseObject<Integer> {
+    private String videoFileId;
+    private String fileId;
+    private String urlType;
+    private Integer width;
+    private Integer height;
+    private String quality;
+    private Integer bandwidth;
+    private Double frameRate;
+
+    public VideoUrl(String videoFileId, String fileId, String urlType, int width, int height, String quality) {
+        this.videoFileId = videoFileId;
+        this.fileId = fileId;
+        this.urlType = urlType;
+        this.width = width;
+        this.height = height;
+        this.quality = quality;
+    }
+}

+ 3 - 2
src/main/java/cn/reghao/dfs/store/model/vo/FilePartRet.java

@@ -1,7 +1,6 @@
 package cn.reghao.dfs.store.model.vo;
 
 import cn.reghao.dfs.store.model.dto.PathUrl;
-import lombok.AllArgsConstructor;
 import lombok.Getter;
 
 /**
@@ -13,15 +12,17 @@ public class FilePartRet {
     private String uploadId;
     private boolean merged;
     private PathUrl pathUrl;
+    private String fileId;
 
     public FilePartRet(String uploadId) {
         this.uploadId = uploadId;
         this.merged = false;
     }
 
-    public FilePartRet(String uploadId, PathUrl pathUrl) {
+    public FilePartRet(String uploadId, PathUrl pathUrl, String fileId) {
         this.uploadId = uploadId;
         this.merged = true;
         this.pathUrl = pathUrl;
+        this.fileId = fileId;
     }
 }

+ 11 - 0
src/main/java/cn/reghao/dfs/store/model/vo/ImageFileRet.java

@@ -0,0 +1,11 @@
+package cn.reghao.dfs.store.model.vo;
+
+/**
+ * @author reghao
+ * @date 2022-08-05 18:06:08
+ */
+public class ImageFileRet {
+    private String uploadId;
+    private String imageFileId;
+    private String coverUrl;
+}

+ 1 - 0
src/main/java/cn/reghao/dfs/store/model/vo/UploadFileRet.java

@@ -15,5 +15,6 @@ public class UploadFileRet implements Serializable {
     private static final long serialVersionUID = 1L;
 
     private String uploadId;
+    private String fileId;
     private String url;
 }

+ 10 - 6
src/main/java/cn/reghao/dfs/store/model/vo/VideoFileRet.java

@@ -1,5 +1,7 @@
 package cn.reghao.dfs.store.model.vo;
 
+import cn.reghao.dfs.store.model.po.VideoFile;
+
 /**
  * @author reghao
  * @date 2022-07-23 06:21:32
@@ -7,20 +9,22 @@ package cn.reghao.dfs.store.model.vo;
 public class VideoFileRet {
     private String uploadId;
     private boolean merged;
-    private String videoUrl;
-    private String coverUrl;
+    private String videoFileId;
+    private Boolean horizontal;
     private Integer duration;
+    private String coverUrl;
 
     public VideoFileRet(String uploadId) {
         this.uploadId = uploadId;
         this.merged = false;
     }
 
-    public VideoFileRet(String uploadId, String videoUrl, String coverUrl, Integer duration) {
+    public VideoFileRet(String uploadId, VideoFile videoFile) {
         this.uploadId = uploadId;
         this.merged = true;
-        this.videoUrl = videoUrl;
-        this.coverUrl = coverUrl;
-        this.duration = duration;
+        this.videoFileId = videoFile.getVideoFileId();
+        this.duration = videoFile.getDuration();
+        this.horizontal = videoFile.getHorizontal();
+        this.coverUrl = videoFile.getCoverUrl();
     }
 }

+ 29 - 0
src/main/java/cn/reghao/dfs/store/rpc/MediaUrlServiceImpl.java

@@ -0,0 +1,29 @@
+package cn.reghao.dfs.store.rpc;
+
+import cn.reghao.dfs.api.iface.MediaUrlService;
+import cn.reghao.dfs.store.db.mapper.VideoUrlMapper;
+import cn.reghao.dfs.api.dto.VideoUrlDto;
+import org.apache.dubbo.config.annotation.DubboService;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2022-08-05 15:04:19
+ */
+@DubboService
+@Service
+public class MediaUrlServiceImpl implements MediaUrlService {
+    private final VideoUrlMapper videoUrlMapper;
+
+    public MediaUrlServiceImpl(VideoUrlMapper videoUrlMapper) {
+        this.videoUrlMapper = videoUrlMapper;
+    }
+
+    @Override
+    public List<VideoUrlDto> getMp4Urls(String videoFileId) {
+        List<VideoUrlDto> urls = videoUrlMapper.findByVideoFileId(videoFileId);
+        return urls;
+    }
+}

+ 6 - 4
src/main/java/cn/reghao/dfs/store/service/FileUploadService.java

@@ -98,7 +98,7 @@ public class FileUploadService {
             String fileId = fileInfo.getFileId();
             String uploadId = fileRepository.getOrCreateUploadId(fileInfo.getFileId());
             String url = fileRepository.getPathUrlByFileId(fileId);
-            return new UploadFileRet(uploadId, url);
+            return new UploadFileRet(uploadId, fileId, url);
         } else {
             int size = bytes.length;
             String filename = uploadedFile.getFilename();
@@ -120,7 +120,7 @@ public class FileUploadService {
 
             fileRepository.saveFile(fileId, fileContentType, pathUrl);
             String url = pathUrl.getUrl();
-            return new UploadFileRet(uploadId, url);
+            return new UploadFileRet(uploadId, fileId, url);
         }
     }
 
@@ -140,7 +140,9 @@ public class FileUploadService {
         FileInfo fileInfo = fileRepository.getFileInfoByFileId(uploadId);
         // 没有检查文件的 sha256sum, 存在安全隐患
         if (fileInfo.getUploaded()) {
-            return new FilePartRet(uploadId, null);
+            FileUrlDto fileUrlDto = fileUrlService.getFileUrl(uploadId);
+            PathUrl pathUrl = new PathUrl(fileUrlDto.getAbsolutePath(), fileUrlDto.getUrl(), fileUrlDto.getPath());
+            return new FilePartRet(uploadId, pathUrl, fileUrlDto.getFileId());
         }
 
         String fileId = fileInfo.getFileId();
@@ -175,7 +177,7 @@ public class FileUploadService {
             FileContentType fileType = fileTypeService.getFileType(fileInfo.getContentType(), absolutePath);
             fileRepository.saveFile(fileId, fileType, pathUrl);
             map.remove(fileId);
-            return new FilePartRet(uploadId, pathUrl);
+            return new FilePartRet(uploadId, pathUrl, fileId);
         }
     }
 }

+ 2 - 18
src/main/java/cn/reghao/dfs/store/service/FileUrlService.java

@@ -3,7 +3,6 @@ package cn.reghao.dfs.store.service;
 import cn.reghao.dfs.store.config.DfsProperties;
 import cn.reghao.dfs.store.model.dto.FileUrlDto;
 import cn.reghao.dfs.store.util.store.LoadBalancer;
-import cn.reghao.dfs.store.util.store.LocalStores;
 import cn.reghao.dfs.store.util.store.StoreDir;
 import cn.reghao.dfs.store.model.dto.PathUrl;
 import cn.reghao.dfs.store.db.mapper.FileUrlMapper;
@@ -48,32 +47,17 @@ public class FileUrlService {
             throws IOException, NoSuchAlgorithmException {
         //StoreDir storeDir = loadBalancer.getStoreDir(fileSize, sha256sum);
         StoreDir storeDir = loadBalancer.getStoreDir(fileSize);
-        String blockId = storeDir.getBlockId();
         String fileDir = storeDir.getAbsoluteDirPath();
 
         String filePath = String.format("%s/%s.%s", fileDir, fileId, suffix);
         String url = String.format("//%s/%s", domain, path);
-        return new PathUrl(blockId, filePath, url, path);
-    }
-
-    @Deprecated
-    public PathUrl getImagePathAndUrl(String sha256sum, String uploadId, long fileSize, String fileId, String suffix,
-                                      int width, int height) throws IOException, NoSuchAlgorithmException {
-        //StoreDir storeDir = loadBalancer.getStoreDir(fileSize, sha256sum);
-        StoreDir storeDir = loadBalancer.getStoreDir(fileSize);
-        String blockId = storeDir.getBlockId();
-        String fileDir = storeDir.getAbsoluteDirPath();
-
-        String filePath = String.format("%s/%s_%sx%s.%s", fileDir, fileId, width, height, suffix);
-        String path = String.format("video/%s.%s", uploadId, suffix);
-        String url = String.format("//%s/image/%s.%s", domain, uploadId, suffix);
-        return new PathUrl(blockId, filePath, url, path);
+        return new PathUrl(filePath, url, path);
     }
 
     public String getFilePath(String uploadId) {
         FileUrlDto fileUrlDto = fileUrlMapper.findByUploadId(uploadId);
         if (fileUrlDto != null) {
-            return LocalStores.getBaseDir(fileUrlDto.getBlockId()) + "/" + fileUrlDto.getRelativePath();
+            return fileUrlDto.getAbsolutePath();
         }
         return null;
     }

+ 22 - 1
src/main/java/cn/reghao/dfs/store/service/media/ImageFileService.java

@@ -1,12 +1,33 @@
 package cn.reghao.dfs.store.service.media;
 
+import cn.reghao.dfs.store.db.mapper.ImageFileMapper;
+import cn.reghao.dfs.store.db.mapper.ImageUrlMapper;
+import cn.reghao.dfs.store.model.po.ImageFile;
+import cn.reghao.dfs.store.model.po.ImageUrl;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
 
 /**
  * @author reghao
  * @date 2021-08-04 17:29:47
  */
 @Slf4j
-//@Service
+@Service
 public class ImageFileService {
+    private final ImageFileMapper imageFileMapper;
+    private final ImageUrlMapper imageUrlMapper;
+
+    public ImageFileService(ImageFileMapper imageFileMapper, ImageUrlMapper imageUrlMapper) {
+        this.imageFileMapper = imageFileMapper;
+        this.imageUrlMapper = imageUrlMapper;
+    }
+
+    public void saveImage(ImageFile imageFile, List<ImageUrl> imageUrls) {
+        if (!imageUrls.isEmpty()) {
+            imageFileMapper.save(imageFile);
+            imageUrlMapper.saveAll(imageUrls);
+        }
+    }
 }

+ 30 - 0
src/main/java/cn/reghao/dfs/store/service/media/MediaQuality.java

@@ -0,0 +1,30 @@
+package cn.reghao.dfs.store.service.media;
+
+/**
+ * @author reghao
+ * @date 2022-08-05 10:06:08
+ */
+public class MediaQuality {
+    public static String getQuality(int width, int height, boolean horizontal) {
+        int resolution = horizontal ? width : height;
+        if (resolution >= 7680) {
+            return "8k";
+        } else if (resolution >= 3840) {
+            return "4k";
+        } else if (resolution >= 2560) {
+            return "2k";
+        } else if (resolution >= 1920) {
+            return "1080p";
+        } else if (resolution >= 1280) {
+            return "720p";
+        } else if (resolution >= 854) {
+            return "480p";
+        } else if (resolution >= 640) {
+            return "360p";
+        } else if (resolution >= 512) {
+            return "288p";
+        } else {
+            return "144p";
+        }
+    }
+}

+ 43 - 23
src/main/java/cn/reghao/dfs/store/service/media/VideoFileService.java

@@ -1,18 +1,25 @@
 package cn.reghao.dfs.store.service.media;
 
+import cn.reghao.dfs.store.db.mapper.VideoUrlMapper;
 import cn.reghao.dfs.store.model.constant.VideoUrlType;
 import cn.reghao.dfs.store.model.dto.UploadedFile;
+import cn.reghao.dfs.store.model.po.ImageFile;
+import cn.reghao.dfs.store.model.po.ImageUrl;
+import cn.reghao.dfs.store.model.po.VideoUrl;
 import cn.reghao.dfs.store.model.vo.UploadFileRet;
 import cn.reghao.dfs.store.service.FileUploadService;
+import cn.reghao.dfs.store.util.media.ImageOps;
 import cn.reghao.dfs.store.util.media.VideoOps;
 import cn.reghao.dfs.store.model.dto.PathUrl;
 import cn.reghao.dfs.store.db.mapper.VideoFileMapper;
 import cn.reghao.dfs.store.model.po.VideoFile;
+import cn.reghao.jutil.tool.id.IdGenerator;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.io.*;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -23,11 +30,18 @@ import java.util.Map;
 @Service
 public class VideoFileService {
     private final VideoFileMapper videoFileMapper;
+    private final VideoUrlMapper videoUrlMapper;
     private final FileUploadService fileUploadService;
+    private final ImageFileService imageFileService;
+    private final IdGenerator idGenerator;
 
-    public VideoFileService(VideoFileMapper videoFileMapper, FileUploadService fileUploadService) {
+    public VideoFileService(VideoFileMapper videoFileMapper, VideoUrlMapper videoUrlMapper,
+                            FileUploadService fileUploadService, ImageFileService imageFileService) {
         this.videoFileMapper = videoFileMapper;
+        this.videoUrlMapper = videoUrlMapper;
         this.fileUploadService = fileUploadService;
+        this.imageFileService = imageFileService;
+        this.idGenerator = new IdGenerator("video-file-id");
     }
 
     /**
@@ -45,12 +59,12 @@ public class VideoFileService {
         String path = pathUrl.getAbsolutePath();
         String url = pathUrl.getUrl();
 
-        VideoFile videoFile = new VideoFile(fileId, VideoUrlType.mp4.getName(), url);
+        VideoFile videoFile = new VideoFile(idGenerator.getUuid());
         File videoLocalFile = new File(path);
-        log.info("process video {} with FFmpeg...", videoFile.getFileId());
-        setVideoProps(videoFile, videoLocalFile);
+        //log.info("process video {} with FFmpeg...", videoFile.getFileId());
+        setVideoProps(videoFile, fileId, videoLocalFile);
         setVideoCover(videoFile, videoLocalFile);
-        log.info("video {} processed...", videoFile.getFileId());
+        //log.info("video {} processed...", videoFile.getFileId());
 
         videoFileMapper.save(videoFile);
         return videoFile;
@@ -63,22 +77,23 @@ public class VideoFileService {
      * @return
      * @date 2021-08-18 上午10:08
      */
-    private void setVideoProps(VideoFile videoFile, File file) throws IOException {
+    private void setVideoProps(VideoFile videoFile, String fileId, File file) throws IOException {
         Map<String, Object> map = VideoOps.videoProps(file);
         int width = (Integer) map.get("width");
         int height = (Integer) map.get("height");
+        boolean horizontal = width >= height;
+        int duration = ((Long) map.get("duration")).intValue();
         double fps = (Double) map.get("fps");
         int frameLength = (Integer) map.get("frameLength");
         int length = (Integer) map.get("length");
-        int duration = ((Long) map.get("duration")).intValue();
         String rotate = (String) map.get("rotate");
 
         videoFile.setDuration(duration);
-        videoFile.setFrameRate(fps);
-        videoFile.setWidth(width);
-        videoFile.setHeight(height);
-        videoFile.setHorizontal(width >= height);
-        videoFile.setRotate(rotate);
+        videoFile.setHorizontal(horizontal);
+        String videoFileId = videoFile.getVideoFileId();
+        String quality = MediaQuality.getQuality(width, height, horizontal);
+        VideoUrl videoUrl = new VideoUrl(videoFileId, fileId, VideoUrlType.mp4.getName(), width, height, quality);
+        videoUrlMapper.save(videoUrl);
     }
 
     /**
@@ -93,26 +108,31 @@ public class VideoFileService {
         byte[] bytes = outputStream.toByteArray();
         outputStream.close();
 
+        ImageOps.Size size = ImageOps.info(new ByteArrayInputStream(bytes));
+        boolean horizontal = size.getWidth() > size.getWidth();
+
         String filename = "default.jpg";
-        long size = bytes.length;
+        long len = bytes.length;
         String contentType = "image/jpeg";
         InputStream in = new ByteArrayInputStream(bytes);
-        UploadedFile uploadedFile = new UploadedFile(filename, size, contentType, in);
+        UploadedFile uploadedFile = new UploadedFile(filename, len, contentType, in);
         UploadFileRet uploadFileRet = fileUploadService.put(uploadedFile);
-        videoFile.setBaseCoverUrl(uploadFileRet.getUrl());
+        String imageFileId = idGenerator.getUuid();
+
+        ImageFile imageFile = new ImageFile(imageFileId, horizontal);
+        String fileId = uploadFileRet.getFileId();
+        ImageUrl imageUrl = new ImageUrl(imageFileId, fileId, size.getWidth(), size.getHeight());
+        imageFileService.saveImage(imageFile, List.of(imageUrl));
+
+        videoFile.setCoverUrl(uploadFileRet.getUrl());
     }
 
     @Transactional(rollbackFor = Exception.class)
-    public String setVideoCover(String fileId, UploadedFile uploadedFile) throws Exception {
-        VideoFile videoFile = videoFileMapper.findByFileId(fileId);
-        if (videoFile == null) {
-            return null;
-        }
-
+    public String setVideoCover(String videoFileId, UploadedFile uploadedFile) throws Exception {
         UploadFileRet uploadFileRet = fileUploadService.put(uploadedFile);
         String url = uploadFileRet.getUrl();
-        videoFile.setBaseCoverUrl(url);
-        videoFileMapper.updateSetCover(fileId, url);
+        /*videoFile.setCoverUrl(url);
+        videoFileMapper.updateSetCover(videoFileId, url);*/
         return url;
     }
 }

+ 1 - 0
src/main/java/cn/reghao/dfs/store/util/store/LocalStores.java

@@ -87,6 +87,7 @@ public class LocalStores {
         throw new Exception(String.format("没有找到 %s 对应的 blockId", absolutePath));
     }
 
+    @Deprecated
     public static String getRelativePath(String absolutePath) throws Exception {
         for (Map.Entry<String, LocalStore> entry : storeMap.entrySet()) {
             LocalStore localStore = entry.getValue();

+ 4 - 1
src/main/resources/application-dev.yml

@@ -1,6 +1,9 @@
+dubbo:
+  registry:
+    address: zookeeper://localhost:2181
 spring:
   datasource:
-    url: jdbc:mysql://localhost:3306/reghao_vid_rdb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8
+    url: jdbc:mysql://localhost:3306/reghao_vid_file_rdb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8
     username: dev
     password: Dev@123456
 dfs:

+ 10 - 2
src/main/resources/application.yml

@@ -1,10 +1,18 @@
 server:
   port: 8002
+dubbo:
+  scan:
+    base-packages: cn.reghao.dfs.store.rpc
+  protocol:
+    name: dubbo
+    port: 8102
+  registry:
+    address: zookeeper://localhost:2181
 spring:
   servlet:
     multipart:
-      max-request-size: 20GB
-      max-file-size: 20GB
+      max-request-size: 30MB
+      max-file-size: 20MB
   application:
     name: dfs-store
   profiles:

+ 2 - 10
src/main/resources/mapper/FileInfoMapper.xml

@@ -4,17 +4,9 @@
 <mapper namespace="cn.reghao.dfs.store.db.mapper.FileInfoMapper">
     <insert id="save" useGeneratedKeys="true" keyProperty="id">
         insert into file_info
-        (`id`,`deleted`,`create_time`,`update_time`,`file_id`,`sha256sum`,`filename`,`suffix`,`size`,`file_type`,`content_type`,`uploaded`)
+        (`id`,`deleted`,`create_time`,`update_time`,`file_id`,`sha256sum`,`filename`,`suffix`,`size`,`file_type`,`content_type`,`uploaded`,`original`)
         values 
-        (#{id},#{deleted},#{createTime},#{updateTime},#{fileId},#{sha256sum},#{filename},#{suffix},#{size},#{fileType},#{contentType},#{uploaded})
-    </insert>
-    <insert id="saveAll" useGeneratedKeys="true" keyProperty="id">
-        insert into file_info
-        (`id`,`deleted`,`create_time`,`update_time`,`file_id`,`sha256sum`,`filename`,`suffix`,`size`,`file_type`)
-        values
-        <foreach collection="list" item="item" index="index" separator=",">
-            (#{item.id},#{item.deleted},#{item.createTime},#{item.updateTime},#{item.fileId},#{item.sha256sum},#{item.filename},#{item.suffix},#{item.size},#{item.fileType})
-        </foreach>
+        (#{id},#{deleted},#{createTime},#{updateTime},#{fileId},#{sha256sum},#{filename},#{suffix},#{size},#{fileType},#{contentType},#{uploaded},#{original})
     </insert>
 
     <update id="updateSetUploaded1">

+ 4 - 4
src/main/resources/mapper/FileUrlMapper.xml

@@ -4,13 +4,13 @@
 <mapper namespace="cn.reghao.dfs.store.db.mapper.FileUrlMapper">
     <insert id="save" useGeneratedKeys="true" keyProperty="id">
         insert into file_url
-        (`id`,`deleted`,`create_time`,`update_time`,`file_id`,`block_id`,`relative_path`,`url`,`path`,`group`,`node`)
+        (`id`,`deleted`,`create_time`,`update_time`,`file_id`,`block_id`,`absolute_path`,`url`,`path`,`group`,`node`)
         values 
-        (#{id},#{deleted},#{createTime},#{updateTime},#{fileId},#{blockId},#{relativePath},#{url},#{path},#{group},#{node})
+        (#{id},#{deleted},#{createTime},#{updateTime},#{fileId},#{blockId},#{absolutePath},#{url},#{path},#{group},#{node})
     </insert>
 
     <update id="updateSetFileUrl">
-        update file_url set update_time=now(),block_id=#{blockId},relative_path=#{relativePath}
+        update file_url set update_time=now(),block_id=#{blockId},absolute_path=#{absolutePath}
         where file_id=#{fileId}
     </update>
 
@@ -18,7 +18,7 @@
         select * from file_url
     </select>
     <select id="findByUploadId" resultType="cn.reghao.dfs.store.model.dto.FileUrlDto">
-        select info.id,info.filename,url.block_id,url.path,url.url,url.relative_path as relativePath from file_url url
+        select info.id,info.filename,url.path,url.url,url.absolute_path as absolutePath from file_url url
         inner join file_user fileUser
         inner join file_info info
         on fileUser.file_id=url.file_id and info.file_id=url.file_id and fileUser.upload_id=#{uploadId}

+ 4 - 16
src/main/resources/mapper/ImageFileMapper.xml

@@ -4,28 +4,16 @@
 <mapper namespace="cn.reghao.dfs.store.db.mapper.ImageFileMapper">
     <insert id="save" useGeneratedKeys="true" keyProperty="id">
         insert into image_file
-        (`id`,`deleted`,`create_time`,`update_time`,`file_id`,`base_url`,`width`,`height`)
+        (`id`,`deleted`,`create_time`,`update_time`,`image_file_id`,`horizontal`)
         values 
-        (#{id},#{deleted},#{createTime},#{updateTime},#{fileId},#{baseUrl},#{width},#{height})
+        (#{id},#{deleted},#{createTime},#{updateTime},#{imageFileId},#{horizontal})
     </insert>
     <insert id="saveAll" useGeneratedKeys="true" keyProperty="id">
         insert into image_file
-        (`id`,`deleted`,`create_time`,`update_time`,`file_id`,`base_url`,`width`,`height`)
+        (`id`,`deleted`,`create_time`,`update_time`,`image_file_id`,`horizontal`)
         values
         <foreach collection="list" item="item" index="index" separator=",">
-            (#{item.id},#{item.deleted},#{item.createTime},#{item.updateTime},#{item.fileId},#{item.baseUrl},#{item.width},#{item.height})
+            (#{item.id},#{item.deleted},#{item.createTime},#{item.updateTime},#{item.imageFileId},#{item.horizontal})
         </foreach>
     </insert>
-
-    <update id="updateSetUrl">
-        update image_file set update_time=now(), url=#{url}
-        where file_id=#{fileId}
-    </update>
-
-    <select id="findByFileId" resultType="cn.reghao.dfs.store.model.po.ImageFile">
-        select * from image_file where file_id=#{fileId}
-    </select>
-    <select id="findByFileIds" resultType="cn.reghao.dfs.store.model.po.ImageFile">
-        select * from image_file where file_id in #{list}
-    </select>
 </mapper>

+ 23 - 0
src/main/resources/mapper/ImageUrlMapper.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="cn.reghao.dfs.store.db.mapper.ImageUrlMapper">
+    <insert id="save" useGeneratedKeys="true" keyProperty="id">
+        insert into image_url
+        (`image_file_id`,`file_id`,`width`,`height`)
+        values 
+        (#{imageFileId},#{fileId},#{width},#{height})
+    </insert>
+    <insert id="saveAll" useGeneratedKeys="true" keyProperty="id">
+        insert into image_url
+        (`image_file_id`,`file_id`,`width`,`height`)
+        values
+        <foreach collection="list" item="item" index="index" separator=",">
+            (#{item.imageFileId},#{item.fileId},#{item.width},#{item.height})
+        </foreach>
+    </insert>
+
+    <select id="findByImageFileId" resultType="cn.reghao.dfs.store.model.po.ImageUrl">
+        select * from image_url where image_file_id=#{imageFileId}
+    </select>
+</mapper>

+ 3 - 14
src/main/resources/mapper/VideoFileMapper.xml

@@ -4,24 +4,13 @@
 <mapper namespace="cn.reghao.dfs.store.db.mapper.VideoFileMapper">
     <insert id="save" useGeneratedKeys="true" keyProperty="id">
         insert into video_file
-        (`id`,`deleted`,`create_time`,`update_time`,`file_id`,`bandwidth`,`frame_rate`,`width`,`height`,`horizontal`,`rotate`,`url_type`,`base_url`,`backup_url`,`duration`,`base_cover_url`)
+        (`id`,`deleted`,`create_time`,`update_time`,`video_file_id`,`horizontal`,`duration`,`cover_url`)
         values 
-        (#{id},#{deleted},#{createTime},#{updateTime},#{fileId},#{bandwidth},#{frameRate},#{width},#{height},#{horizontal},#{rotate},#{urlType},#{baseUrl},#{backupUrl},#{duration},#{baseCoverUrl})
+        (#{id},#{deleted},#{createTime},#{updateTime},#{videoFileId},#{horizontal},#{duration},#{coverUrl})
     </insert>
 
     <update id="updateSetCover">
-        update video_file set update_time=now(), base_cover_url=#{coverUrl}
+        update video_file set update_time=now(), cover_url=#{coverUrl}
         where file_id=#{fileId}
     </update>
-    <update id="updateSetUrl">
-        update video_file set update_time=now(), base_url=#{baseUrl}, base_cover_url=#{baseCoverUrl}
-        where file_id=#{fileId}
-    </update>
-
-    <select id="findByFileId" resultType="cn.reghao.dfs.store.model.po.VideoFile">
-        select * from video_file where file_id=#{fileId} order by create_time desc limit 1
-    </select>
-    <select id="findByMatchBaseUrl" resultType="cn.reghao.dfs.store.model.po.VideoFile">
-        select * from video_file where base_url like concat('%',#{pattern},'%')
-    </select>
 </mapper>

+ 18 - 0
src/main/resources/mapper/VideoUrlMapper.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="cn.reghao.dfs.store.db.mapper.VideoUrlMapper">
+    <insert id="save" useGeneratedKeys="true" keyProperty="id">
+        insert into video_url
+        (`video_file_id`,`file_id`,`url_type`,`width`,`height`,`quality`,`bandwidth`,`frame_rate`)
+        values
+        (#{videoFileId},#{fileId},#{urlType},#{width},#{height},#{quality},#{bandwidth},#{frameRate})
+    </insert>
+
+    <select id="findByVideoFileId" resultType="cn.reghao.dfs.api.dto.VideoUrlDto">
+        select fileUrl.url,fileUrl.path,videoUrl.url_type as type,videoUrl.width,videoUrl.height,videoUrl.quality
+        from video_url videoUrl
+        inner join file_url fileUrl
+        on videoUrl.file_id=fileUrl.file_id and videoUrl.video_file_id=#{videoFileId}
+    </select>
+</mapper>

+ 45 - 10
src/test/java/ConsistentCheckTest.java

@@ -1,7 +1,10 @@
-import cn.reghao.dfs.store.db.mapper.FileInfoMapper;
-import cn.reghao.dfs.store.db.mapper.FileUrlMapper;
-import cn.reghao.dfs.store.db.mapper.FileUserMapper;
-import cn.reghao.dfs.store.db.mapper.VideoFileMapper;
+import cn.reghao.dfs.store.db.mapper.*;
+import cn.reghao.dfs.store.model.constant.VideoUrlType;
+import cn.reghao.dfs.store.model.dto.UploadedFile;
+import cn.reghao.dfs.store.model.po.VideoUrl;
+import cn.reghao.dfs.store.model.vo.UploadFileRet;
+import cn.reghao.dfs.store.service.FileUploadService;
+import cn.reghao.dfs.store.service.media.MediaQuality;
 import cn.reghao.jutil.jdk.security.DigestUtil;
 import cn.reghao.dfs.store.DfsStoreApplication;
 import cn.reghao.dfs.store.model.po.FileInfo;
@@ -15,9 +18,7 @@ import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.context.ActiveProfiles;
 import org.springframework.test.context.junit4.SpringRunner;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
+import java.io.*;
 import java.nio.file.*;
 import java.nio.file.attribute.BasicFileAttributes;
 import java.security.NoSuchAlgorithmException;
@@ -91,9 +92,7 @@ public class ConsistentCheckTest {
                             List<FileUrl> list = fileUrlMapper.findByFileId(fileId);
                             if (list.size() == 1) {
                                 FileUrl fileUrl = fileUrlMapper.findByFileId(fileId).get(0);
-                                String blockId = fileUrl.getBlockId();
-                                String relativePath = fileUrl.getRelativePath();
-                                String localFilePath = LocalStores.getMountedOn(blockId) + File.separator + relativePath;
+                                String localFilePath = fileUrl.getAbsolutePath();
                                 if (!localFilePath.equals(absolutePath)) {
                                     log.error("{} 的 LocalFilePath 不存在", fileId);
                                     return FileVisitResult.CONTINUE;
@@ -129,4 +128,40 @@ public class ConsistentCheckTest {
         walkDir(dirPath);
         log.info("total file = {}", count);
     }
+
+    @Test
+    public void test22() {
+
+    }
+
+    @Autowired
+    FileUploadService fileUploadService;
+    @Autowired
+    VideoUrlMapper videoUrlMapper;
+    @Test
+    public void test2() throws Exception {
+        String videoFileId = "wOdK71938E";
+        String filePath = "/home/reghao/Downloads/mp4/0/video_720.mp4";
+        saveVideoFile(videoFileId, filePath);
+    }
+
+    private void saveVideoFile(String videoFileId, String filePath) throws Exception {
+        File file = new File(filePath);
+
+        String filename = file.getName();
+        long size = file.length();
+        String contentType = "video/mp4";
+        InputStream inputStream = new FileInputStream(file);
+
+        UploadedFile uploadedFile = new UploadedFile(filename, size, contentType, inputStream);
+        UploadFileRet fileRet = fileUploadService.put(uploadedFile);
+
+        String fileId = fileRet.getFileId();
+        int width = 1280;
+        int height = 720;
+        boolean horizontal = width > height;
+        String quality = MediaQuality.getQuality(width, height, horizontal);
+        VideoUrl videoUrl = new VideoUrl(videoFileId, fileId, VideoUrlType.mp4.getName(), width, height, quality);
+        videoUrlMapper.save(videoUrl);
+    }
 }