reghao 3 anni fa
parent
commit
c6d72fb7e9

+ 251 - 0
src/main/java/cn/reghao/dfs/store/oss/controller/BucketController.java

@@ -0,0 +1,251 @@
+package cn.reghao.dfs.store.oss.controller;
+
+import cn.reghao.jutil.jdk.result.WebBody;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @author reghao
+ * @date 2022-11-21 15:12:11
+ */
+@Api(tags = "存储桶接口")
+@RestController
+@RequestMapping("/bucket")
+public class BucketController {
+    @ApiOperation(value = "删除指定的存储桶")
+    @DeleteMapping(value = "/", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String deleteBucket() {
+        return WebBody.success();
+    }
+
+    @ApiOperation(value = "删除指定存储桶的 CORS 配置")
+    @DeleteMapping(value = "/", params = {"cors"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String deleteBucketCors() {
+        return WebBody.success();
+    }
+
+    @ApiOperation(value = "删除指定存储桶的默认加密配置")
+    @DeleteMapping(value = "/", params = {"encryption"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String deleteBucketEncryption() {
+        return WebBody.success();
+    }
+
+    @ApiOperation(value = "删除指定存储桶的策略配置")
+    @DeleteMapping(value = "/", params = {"policy"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String deleteBucketPolicy() {
+        return WebBody.success();
+    }
+
+    @ApiOperation(value = "删除指定存储桶的复制配置")
+    @DeleteMapping(value = "/", params = {"replication"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String deleteBucketReplication() {
+        return WebBody.success();
+    }
+
+    @ApiOperation(value = "删除指定存储桶的静态网站托管配置")
+    @DeleteMapping(value = "/", params = {"website"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String deleteBucketWebsite() {
+        return WebBody.success();
+    }
+
+    @ApiOperation(value = "删除指定存储桶的生命周期配置")
+    @DeleteMapping(value = "/", params = {"lifecycle"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String deleteBucketLifecycle() {
+        return WebBody.success();
+    }
+
+    @ApiOperation(value = "删除指定存储桶的某个清单任务")
+    @DeleteMapping(value = "/", params = {"inventory"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String deleteBucketInventoryConfiguration(@RequestParam("id") String id) {
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取存储桶的 ACL")
+    @GetMapping(value = "/", params = {"acl"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String getBucketAcl() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取存储桶的回调通知配置")
+    @GetMapping(value = "/", params = {"notification"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String getBucketNotification() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取存储桶中的部分对象")
+    @GetMapping(value = "/", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String getBucket(@RequestParam("listType") int listType) {
+        // listType = 2
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取存储桶的 cors 配置")
+    @GetMapping(value = "/", params = {"cors"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String getBucketCors() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取存储桶的默认加密配置")
+    @GetMapping(value = "/", params = {"encryption"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String getBucketEncryption() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取存储桶的策略配置")
+    @GetMapping(value = "/", params = {"uploadId"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String getBucketPolicy() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取存储桶的复制配置信息")
+    @GetMapping(value = "/", params = {"replication"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String getBucketReplication() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取存储桶的静态网站托管配置")
+    @GetMapping(value = "/", params = {"website"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String getBucketWebsite() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取存储桶的生命周期规则")
+    @GetMapping(value = "/", params = {"lifecycle"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String getBucketLifecycle() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取存储桶的默认保存周期策略")
+    @GetMapping(value = "/", params = {"object-lock"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String getBucketObjectLockConfiguration() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取存储桶中设置的标签")
+    @GetMapping(value = "/", params = {"tagging"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String getBucketTagging() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取存储桶的传输加速规则")
+    @GetMapping(value = "/", params = {"accelerate"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String getBucketAccelerate() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取存储桶中用户的任务清单")
+    @GetMapping(value = "/", params = {"inventory", "id"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String getBucketInventoryConfiguration(@PathVariable("id") String id) {
+        return WebBody.success();
+    }
+
+    @ApiOperation("检查存储桶是否存在")
+    @RequestMapping(value = "/", method = RequestMethod.HEAD, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String headBucket() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取存储桶的访问日志保存规则")
+    @GetMapping(value = "/", params = {"logging"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String getBucketLogging() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取存储桶中正在进行的分片上传")
+    @GetMapping(value = "/", params = {"uploads"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String listMultipartUploads(@RequestParam("maxUploads") int maxUploads) {
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取存储桶的所有清单任务")
+    @GetMapping(value = "/", params = {"inventory", "continuationToken"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String listBucketInventoryConfigurations(@RequestParam("continuationToken") String continuationToken) {
+        return WebBody.success();
+    }
+
+    @ApiOperation("创建或修改存储桶的回调通知配置")
+    @PutMapping(value = "/", params = {"notification"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String putBucketNotification() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("创建一个存储桶")
+    @PutMapping(value = "/", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String putBucket() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("添加或修改存储桶的 CORS 配置")
+    @PutMapping(value = "/", params = {"cors"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String putBucketCors() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("添加或修改存储桶的 ACL 配置")
+    @PutMapping(value = "/", params = {"acl"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String putBucketAcl() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("添加或修改存储桶的加密配置")
+    @PutMapping(value = "/", params = {"encryption"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String putBucketEncryption() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("添加或修改存储桶的权限策略配置")
+    @PutMapping(value = "/", params = {"policy"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String putBucketPolicy() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("添加或修改存储桶的复制配置")
+    @PutMapping(value = "/", params = {"replication"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String putBucketReplication() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("添加或修改存储桶的静态网站配置")
+    @PutMapping(value = "/", params = {"website"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String putBucketWebsite() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("添加或修改存储桶的生命周期配置")
+    @PutMapping(value = "/", params = {"lifecycle"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String putBucketLifecycle() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("添加或修改存储桶的默认保存周期策略")
+    @PutMapping(value = "/", params = {"object-lock"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String putBucketObjectLockConfiguration() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("添加或修改存储桶中设置的标签")
+    @PutMapping(value = "/", params = {"tagging"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String putBucketTagging() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("添加或修改存储桶的传输加速规则")
+    @PutMapping(value = "/", params = {"accelerate"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String putBucketAccelerate() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("添加或修改存储桶中用户的任务清单")
+    @PutMapping(value = "/", params = {"inventory"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String putBucketInventoryConfiguration(@PathVariable("id") String id) {
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取存储桶的访问日志保存规则")
+    @PutMapping(value = "/", params = {"logging"}, produces = MediaType.APPLICATION_JSON_VALUE)
+    public String putBucketLogging() {
+        return WebBody.success();
+    }
+}

+ 149 - 0
src/main/java/cn/reghao/dfs/store/oss/controller/ObjectController.java

@@ -0,0 +1,149 @@
+package cn.reghao.dfs.store.oss.controller;
+
+import cn.reghao.dfs.store.oss.model.object.DeleteObjects;
+import cn.reghao.dfs.store.oss.model.object.PostObject;
+import cn.reghao.jutil.jdk.result.WebBody;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.Map;
+
+/**
+ * @author reghao
+ * @date 2022-11-21 15:12:00
+ */
+@Api(tags = "对象接口")
+@RestController
+@RequestMapping("/object")
+public class ObjectController {
+    @ApiOperation("使用 formdata 上传对象")
+    @PostMapping(value = "/")
+    public String postObject(@RequestParam("key") String key, @RequestParam("file") MultipartFile file) {
+        return WebBody.success();
+    }
+
+    @ApiOperation("上传对象")
+    @PutMapping(value = "/{objectName}")
+    public String putObject(@PathVariable("objectName") String objectName, MultipartFile file) {
+        return WebBody.success();
+    }
+
+    @ApiOperation("创建已存在对象的副本")
+    @PutMapping(value = "/{destinationObject}", params = {"destinationObject"})
+    public String putObjectCopy(@PathVariable("destinationObject") String destinationObject) {
+        return WebBody.success();
+    }
+
+    @ApiOperation("开启或关闭对象的依法保留状态")
+    @PutMapping(value = "/{objectKey}", params = {"legal-hold"})
+    public String putObjectLegalHold(@PathVariable("objectKey") String objectKey) {
+        return WebBody.success();
+    }
+
+    @ApiOperation("设置对象的保留周期")
+    @PutMapping(value = "/{objectKey}", params = {"retention"})
+    public String putObjectRetention(@PathVariable("objectKey") String objectKey) {
+        return WebBody.success();
+    }
+
+    @ApiOperation("设置对象的标签")
+    @PutMapping(value = "/{objectKey}", params = {"tagging"})
+    public String putObjectTagging(@PathVariable("objectKey") String objectKey) {
+        return WebBody.success();
+    }
+
+    @ApiOperation("开启分片上传")
+    @PostMapping(value = "/{objectName}", params = {"uploads"})
+    public String initiateMultipartUpload(@PathVariable("objectName") String objectName) {
+        return WebBody.success();
+    }
+
+    @ApiOperation("分片上传对象")
+    @PutMapping(value = "/{objectName}", params = {"partNumber", "uploadId"})
+    public String uploadPart(@PathVariable("objectName") String objectName,
+                             @RequestParam("partNumber") long partNumber,
+                             @RequestParam("uploadId") String uploadId,
+                             MultipartFile multipartFile) {
+        return WebBody.success();
+    }
+
+    @ApiOperation("复制已存在的对象作为源数据上传分片")
+    @PutMapping(value = "/{objectName}", params = {"partNumber", "uploadId"}, headers = {"x-amz-copy-source"})
+    public String uploadPartCopy(@PathVariable("objectName") String objectName,
+                             @RequestParam("partNumber") long partNumber,
+                             @RequestParam("uploadId") String uploadId,
+                             MultipartFile multipartFile) {
+        return WebBody.success();
+    }
+
+    @ApiOperation(value = "完成分片上传")
+    @PostMapping(value = "/{objectName}", params = {"uploadId"})
+    public String completeMultipartUpload(@PathVariable("objectName") String objectName,
+                                          @RequestParam("uploadId") String uploadId) {
+        return WebBody.success();
+    }
+
+    @ApiOperation(value = "对存储类型为 GLACIER 的对象还原临时副本")
+    @PostMapping(value = "/{objectName}", params = {"restore"})
+    public String postObjectRestore(@PathVariable("objectName") String objectName) {
+        return WebBody.success();
+    }
+
+    @ApiOperation(value = "终止分片上传")
+    @DeleteMapping(value = "/{objectName}", params = {"uploadId"})
+    public String abortMultipartUpload(@PathVariable("objectName") String objectName,
+                                       @RequestParam("uploadId") String uploadId) {
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取对象")
+    @GetMapping(value = "/{objectName}")
+    public String getObject(@PathVariable("objectName") String objectName) {
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取对象的依法保留状态")
+    @GetMapping(value = "/{objectKey}", params = {"legal-hold"})
+    public String getObjectLegalHold(@PathVariable("objectKey") String objectKey) {
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取对象的保留周期")
+    @GetMapping(value = "/{objectKey}", params = {"retention"})
+    public String getObjectRetention(@PathVariable("objectKey") String objectKey) {
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取对象的标签")
+    @GetMapping(value = "/{objectKey}", params = {"tagging"})
+    public String getObjectTagging(@PathVariable("objectKey") String objectKey) {
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取对象的元数据")
+    @RequestMapping(value = "/{objectName}", method = RequestMethod.HEAD)
+    public String headObject(@PathVariable("objectName") String objectName) {
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取分片 uploadId 下的所有分片")
+    @GetMapping(value = "/{objectName}", params = {"uploadId"})
+    public String listParts(@PathVariable("objectName") String objectName, @RequestParam("uploadId") String uploadId) {
+        return WebBody.success();
+    }
+
+    @ApiOperation(value = "删除对象")
+    @DeleteMapping(value = "/{objectName}")
+    public String deleteObject(@PathVariable("objectName") String objectName) {
+        return WebBody.success();
+    }
+
+    @ApiOperation(value = "删除多个对象")
+    @PostMapping(value = "/", params = {"delete"})
+    public String deleteMultipleObjects(DeleteObjects deleteObjects) {
+        return WebBody.success();
+    }
+}

+ 27 - 0
src/main/java/cn/reghao/dfs/store/oss/controller/ServiceController.java

@@ -0,0 +1,27 @@
+package cn.reghao.dfs.store.oss.controller;
+
+import cn.reghao.dfs.store.oss.model.service.ListAllMyBucketsResult;
+import cn.reghao.jutil.jdk.result.WebBody;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author reghao
+ * @date 2022-11-21 15:12:53
+ */
+@Api(tags = "服务接口")
+@RestController
+@RequestMapping("/service")
+public class ServiceController {
+    @ApiOperation("获取请求用户拥有的所有存储桶")
+    @GetMapping(value = "/", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String getObjectLegalHold(@PathVariable("objectKey") String objectKey) {
+        ListAllMyBucketsResult listAllMyBucketsResult = new ListAllMyBucketsResult();
+        return WebBody.success();
+    }
+}

+ 11 - 0
src/main/java/cn/reghao/dfs/store/oss/model/bucket/CorsConfiguration.java

@@ -0,0 +1,11 @@
+package cn.reghao.dfs.store.oss.model.bucket;
+
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2022-11-22 11:29:15
+ */
+public class CorsConfiguration {
+    private List<CorsRule> corsRules;
+}

+ 13 - 0
src/main/java/cn/reghao/dfs/store/oss/model/bucket/CorsRule.java

@@ -0,0 +1,13 @@
+package cn.reghao.dfs.store.oss.model.bucket;
+
+/**
+ * @author reghao
+ * @date 2022-11-22 11:24:02
+ */
+public class CorsRule {
+    private String allowedOrigin;
+    private String allowedMethod;
+    private String allowedHeader;
+    private String maxAgeSeconds;
+    private String exposeHeader;
+}

+ 9 - 0
src/main/java/cn/reghao/dfs/store/oss/model/bucket/Expiration.java

@@ -0,0 +1,9 @@
+package cn.reghao.dfs.store.oss.model.bucket;
+
+/**
+ * @author reghao
+ * @date 2022-11-22 14:27:26
+ */
+public class Expiration {
+    private int days;
+}

+ 9 - 0
src/main/java/cn/reghao/dfs/store/oss/model/bucket/Filter.java

@@ -0,0 +1,9 @@
+package cn.reghao.dfs.store.oss.model.bucket;
+
+/**
+ * @author reghao
+ * @date 2022-11-22 14:27:03
+ */
+public class Filter {
+    private String prefix;
+}

+ 11 - 0
src/main/java/cn/reghao/dfs/store/oss/model/bucket/LifecycleConfiguration.java

@@ -0,0 +1,11 @@
+package cn.reghao.dfs.store.oss.model.bucket;
+
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2022-11-22 14:28:46
+ */
+public class LifecycleConfiguration {
+    private List<Rule> rules;
+}

+ 13 - 0
src/main/java/cn/reghao/dfs/store/oss/model/bucket/Rule.java

@@ -0,0 +1,13 @@
+package cn.reghao.dfs.store.oss.model.bucket;
+
+/**
+ * @author reghao
+ * @date 2022-11-22 14:26:57
+ */
+public class Rule {
+    private String id;
+    private Filter filter;
+    private String status;
+    private Expiration expiration;
+    private Transition transition;
+}

+ 10 - 0
src/main/java/cn/reghao/dfs/store/oss/model/bucket/Transition.java

@@ -0,0 +1,10 @@
+package cn.reghao.dfs.store.oss.model.bucket;
+
+/**
+ * @author reghao
+ * @date 2022-11-22 14:28:15
+ */
+public class Transition {
+    private int days;
+    private String storageClass;
+}

+ 12 - 0
src/main/java/cn/reghao/dfs/store/oss/model/object/DeleteObjects.java

@@ -0,0 +1,12 @@
+package cn.reghao.dfs.store.oss.model.object;
+
+import java.io.Serializable;
+
+/**
+ * @author reghao
+ * @date 2022-11-21 16:14:23
+ */
+public class DeleteObjects implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+}

+ 17 - 0
src/main/java/cn/reghao/dfs/store/oss/model/object/FileAttr.java

@@ -0,0 +1,17 @@
+package cn.reghao.dfs.store.oss.model.object;
+
+import java.io.Serializable;
+
+/**
+ * @author reghao
+ * @date 2022-11-21 10:53:10
+ */
+public class FileAttr implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private String objectId;
+    private String objectName;
+    private String sha256sum;
+    private long size;
+    private String filename;
+}

+ 24 - 0
src/main/java/cn/reghao/dfs/store/oss/model/object/InitiateMultipartUploadResult.java

@@ -0,0 +1,24 @@
+package cn.reghao.dfs.store.oss.model.object;
+
+import lombok.AllArgsConstructor;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+
+/**
+ * @author reghao
+ * @date 2022-11-21 15:45:15
+ */
+@AllArgsConstructor
+@XmlRootElement
+public class InitiateMultipartUploadResult implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @XmlElement
+    private String bucket;
+    @XmlElement
+    private String key;
+    @XmlElement
+    private String uploadId;
+}

+ 24 - 0
src/main/java/cn/reghao/dfs/store/oss/model/object/PostObject.java

@@ -0,0 +1,24 @@
+package cn.reghao.dfs.store.oss.model.object;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * @author reghao
+ * @date 2022-11-21 10:53:54
+ */
+@AllArgsConstructor
+@Getter
+public class PostObject implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @NotBlank
+    private String key;
+    @NotNull
+    private MultipartFile file;
+}

+ 12 - 0
src/main/java/cn/reghao/dfs/store/oss/model/service/Bucket.java

@@ -0,0 +1,12 @@
+package cn.reghao.dfs.store.oss.model.service;
+
+import java.time.LocalDateTime;
+
+/**
+ * @author reghao
+ * @date 2022-11-21 17:31:12
+ */
+public class Bucket {
+    private String name;
+    private LocalDateTime creationDate;
+}

+ 12 - 0
src/main/java/cn/reghao/dfs/store/oss/model/service/ListAllMyBucketsResult.java

@@ -0,0 +1,12 @@
+package cn.reghao.dfs.store.oss.model.service;
+
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2022-11-21 17:32:16
+ */
+public class ListAllMyBucketsResult {
+    private Owner owner;
+    private List<Bucket> buckets;
+}

+ 10 - 0
src/main/java/cn/reghao/dfs/store/oss/model/service/Owner.java

@@ -0,0 +1,10 @@
+package cn.reghao.dfs.store.oss.model.service;
+
+/**
+ * @author reghao
+ * @date 2022-11-21 17:31:06
+ */
+public class Owner {
+    private String id;
+    private String displayName;
+}