故障录波文件查询
This commit is contained in:
parent
73c6b46e40
commit
6d7fac330b
@ -31,6 +31,7 @@
|
||||
<taosdata.verson>3.2.10</taosdata.verson>
|
||||
<disruptor.version>3.4.4</disruptor.version>
|
||||
<aviator.version>5.4.3</aviator.version>
|
||||
<minio.version>8.4.3</minio.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@ -201,6 +202,13 @@
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- minio -->
|
||||
<dependency>
|
||||
<groupId>io.minio</groupId>
|
||||
<artifactId>minio</artifactId>
|
||||
<version>${minio.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
27
das/src/main/java/com/das/common/constant/FileConstants.java
Normal file
27
das/src/main/java/com/das/common/constant/FileConstants.java
Normal file
@ -0,0 +1,27 @@
|
||||
package com.das.common.constant;
|
||||
|
||||
/**
|
||||
* @Author liuyuxia
|
||||
* @ClassName FilesvrConstants
|
||||
* @Date 2018/12/10 0010 11:02
|
||||
* @Version 2.5
|
||||
* @Description 文件服务基础常量
|
||||
**/
|
||||
public class FileConstants {
|
||||
|
||||
public static final String FILE_SEPARATOR = "/";
|
||||
|
||||
public static final String FILE_CHARSET = "UTF-8";
|
||||
|
||||
/**
|
||||
* 递归
|
||||
*/
|
||||
public static final Integer YES_RECURSIVE=1;
|
||||
public static final Integer NO_RECURSIVE=0;
|
||||
|
||||
public static final int META_R = 1001;
|
||||
public static final int META_W = 1002;
|
||||
|
||||
public static final String META_R_NAME = "读";
|
||||
public static final String META_W_NAME = "写";
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package com.das.modules.fdr.config;
|
||||
|
||||
import io.minio.*;
|
||||
import io.minio.errors.*;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@ConditionalOnClass(MinioClient.class)
|
||||
public class MinioConfig {
|
||||
|
||||
@Resource
|
||||
private MinioProperties minioAutoProperties;
|
||||
@Bean
|
||||
public MinioClient minioClient() {
|
||||
log.info("开始初始化MinioClient, url为{}, accessKey为:{}", minioAutoProperties.getUrl(), minioAutoProperties.getAccessKey());
|
||||
MinioClient minioClient = MinioClient
|
||||
.builder()
|
||||
.endpoint(minioAutoProperties.getUrl())
|
||||
.credentials(minioAutoProperties.getAccessKey(), minioAutoProperties.getSecretKey())
|
||||
.build();
|
||||
|
||||
minioClient.setTimeout(
|
||||
minioAutoProperties.getConnectTimeout(),
|
||||
minioAutoProperties.getWriteTimeout(),
|
||||
minioAutoProperties.getReadTimeout()
|
||||
);
|
||||
// Start detection
|
||||
if (minioAutoProperties.isCheckBucket()) {
|
||||
log.info("checkBucket为{}, 开始检测桶是否存在", minioAutoProperties.isCheckBucket());
|
||||
String bucketName = minioAutoProperties.getBucket();
|
||||
if (!checkBucket(bucketName, minioClient)) {
|
||||
log.info("文件桶[{}]不存在, 开始检查是否可以新建桶", bucketName);
|
||||
if (minioAutoProperties.isCreateBucket()) {
|
||||
log.info("createBucket为{},开始新建文件桶", minioAutoProperties.isCreateBucket());
|
||||
createBucket(bucketName, minioClient);
|
||||
}
|
||||
}
|
||||
log.info("文件桶[{}]已存在, minio客户端连接成功!", bucketName);
|
||||
} else {
|
||||
throw new RuntimeException("桶不存在, 请检查桶名称是否正确或者将checkBucket属性改为false");
|
||||
}
|
||||
return minioClient;
|
||||
}
|
||||
|
||||
private boolean checkBucket(String bucketName, MinioClient minioClient) {
|
||||
boolean isExists = false;
|
||||
try {
|
||||
isExists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("failed to check if the bucket exists", e);
|
||||
}
|
||||
return isExists;
|
||||
}
|
||||
|
||||
private void createBucket(String bucketName, MinioClient minioClient) {
|
||||
try {
|
||||
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
|
||||
log.info("文件桶[{}]新建成功, minio客户端已连接", bucketName);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("failed to create default bucket", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package com.das.modules.fdr.config;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.URL;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
@Data
|
||||
@Validated
|
||||
@Component
|
||||
public class MinioProperties {
|
||||
/**
|
||||
* 服务地址
|
||||
*/
|
||||
@NotEmpty(message = "minio服务地址不可为空")
|
||||
@URL(message = "minio服务地址格式错误")
|
||||
@Value("${minio.url}")
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* 认证账户
|
||||
*/
|
||||
@NotEmpty(message = "minio认证账户不可为空")
|
||||
@Value("${minio.accessKey}")
|
||||
private String accessKey;
|
||||
|
||||
/**
|
||||
* 认证密码
|
||||
*/
|
||||
@NotEmpty(message = "minio认证密码不可为空")
|
||||
@Value("${minio.secretKey}")
|
||||
private String secretKey;
|
||||
|
||||
/**
|
||||
* 桶名称, 优先级最低
|
||||
*/
|
||||
@Value("${minio.bucket}")
|
||||
private String bucket;
|
||||
|
||||
/**
|
||||
* 桶不在的时候是否新建桶
|
||||
*/
|
||||
private boolean createBucket = true;
|
||||
|
||||
/**
|
||||
* 启动的时候检查桶是否存在
|
||||
*/
|
||||
private boolean checkBucket = true;
|
||||
|
||||
/**
|
||||
* 设置HTTP连接、写入和读取超时。值为0意味着没有超时
|
||||
* HTTP连接超时,以毫秒为单位。
|
||||
*/
|
||||
private long connectTimeout;
|
||||
|
||||
/**
|
||||
* 设置HTTP连接、写入和读取超时。值为0意味着没有超时
|
||||
* HTTP写超时,以毫秒为单位。
|
||||
*/
|
||||
private long writeTimeout;
|
||||
|
||||
/**
|
||||
* 设置HTTP连接、写入和读取超时。值为0意味着没有超时
|
||||
* HTTP读取超时,以毫秒为单位。
|
||||
*/
|
||||
private long readTimeout;
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.das.modules.fdr.controller;
|
||||
|
||||
import com.das.common.result.R;
|
||||
import com.das.modules.fdr.domain.FileNode;
|
||||
import com.das.modules.fdr.service.FaultRecorderService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 故障录波controller
|
||||
*/
|
||||
@Slf4j
|
||||
@RequestMapping("/api/fdr")
|
||||
@RestController
|
||||
public class FaultRecorderController {
|
||||
|
||||
@Autowired
|
||||
private FaultRecorderService faultRecorderService;
|
||||
|
||||
@RequestMapping(value = "/files", method = RequestMethod.POST)
|
||||
public R<List<FileNode>> findList(@RequestParam(required = false) String name, String startTime, String endTime) {
|
||||
List<FileNode> result = faultRecorderService.getDirOrFileList(name,startTime,endTime);
|
||||
return R.success(result);
|
||||
}
|
||||
}
|
22
das/src/main/java/com/das/modules/fdr/domain/FileNode.java
Normal file
22
das/src/main/java/com/das/modules/fdr/domain/FileNode.java
Normal file
@ -0,0 +1,22 @@
|
||||
package com.das.modules.fdr.domain;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class FileNode {
|
||||
//节点名称
|
||||
private String name;
|
||||
|
||||
// 0代表文件夹,1代表文件
|
||||
private int type;
|
||||
|
||||
private String size;
|
||||
|
||||
private String lastModified;
|
||||
|
||||
private String path;
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.das.modules.fdr.service;
|
||||
|
||||
import com.das.modules.fdr.domain.FileNode;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
public interface FaultRecorderService {
|
||||
List<FileNode> getDirOrFileList(String name,String startTime, String endTime);
|
||||
|
||||
String upload(String parent, String folderName, MultipartFile file);
|
||||
|
||||
void readFileToSteam(String path, OutputStream stream);
|
||||
|
||||
void download(String path, Path tempDir);
|
||||
|
||||
}
|
@ -0,0 +1,218 @@
|
||||
package com.das.modules.fdr.service;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import com.das.common.constant.FileConstants;
|
||||
import com.das.modules.fdr.config.MinioProperties;
|
||||
import com.das.modules.fdr.domain.FileNode;
|
||||
import io.micrometer.common.util.StringUtils;
|
||||
import io.minio.*;
|
||||
import io.minio.messages.Item;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.Path;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class MinioViewsServcie {
|
||||
@Autowired
|
||||
private MinioClient minioClient;
|
||||
|
||||
@Autowired
|
||||
private MinioProperties minioProperties;
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
*
|
||||
* @param bucketName 存储桶
|
||||
* @param objectName 文件名称
|
||||
*/
|
||||
public void removeFile(String bucketName, String objectName, Boolean recursive) throws Exception {
|
||||
Iterable<Result<Item>> results = minioClient.listObjects(
|
||||
ListObjectsArgs.builder().bucket(bucketName).prefix(objectName).recursive(true).build());
|
||||
List<Result<Item>> list = StreamSupport.stream(results.spliterator(), false)
|
||||
.collect(Collectors.toList());
|
||||
if (list.size() >= 2 && !recursive) {
|
||||
throw new IOException("请清空文件后再删除目录");
|
||||
}
|
||||
for (Result<Item> result : results) {
|
||||
Item item = result.get();
|
||||
minioClient.removeObject(
|
||||
RemoveObjectArgs.builder()
|
||||
.bucket(bucketName)
|
||||
.object(item.objectName())
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Boolean deleteFileViews(String path, Boolean recursive) throws IOException {
|
||||
if (StringUtils.isBlank(path)) {
|
||||
throw new IOException("请确认删除文件路径");
|
||||
}
|
||||
Boolean success = null;
|
||||
try {
|
||||
path = path.substring(path.indexOf("/") + 1);
|
||||
removeFile(minioProperties.getBucket(), path, recursive);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
public boolean deleteFile(File file) {
|
||||
return file.delete();
|
||||
}
|
||||
|
||||
|
||||
public String upload(String path, String folderName,MultipartFile file) {
|
||||
String targetFile = null;
|
||||
try {
|
||||
// 上传一个空对象来模拟文件夹
|
||||
if (!StringUtils.isBlank(folderName)){
|
||||
targetFile = path + folderName + FileConstants.FILE_SEPARATOR;
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(new byte[0]);
|
||||
minioClient.putObject(
|
||||
PutObjectArgs.builder()
|
||||
.bucket(minioProperties.getBucket())
|
||||
.object(targetFile)
|
||||
.stream(bais, 0, -1)
|
||||
.build());
|
||||
}
|
||||
else {
|
||||
targetFile= path +"/" + file.getOriginalFilename();
|
||||
uploadFile(minioProperties.getBucket(), file, targetFile, "application/octet-stream");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return targetFile;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 使用MultipartFile进行文件上传
|
||||
*
|
||||
* @param bucketName 存储桶
|
||||
* @param file 文件名
|
||||
* @param objectName 对象名
|
||||
* @param contentType 类型
|
||||
* @throws Exception
|
||||
*/
|
||||
public void uploadFile(String bucketName, MultipartFile file, String objectName, String contentType) throws Exception {
|
||||
InputStream inputStream = file.getInputStream();
|
||||
try{
|
||||
minioClient.putObject(
|
||||
PutObjectArgs.builder()
|
||||
.bucket(bucketName)
|
||||
.object(objectName)
|
||||
.contentType(contentType)
|
||||
.stream(inputStream, inputStream.available(), -1)
|
||||
.build());
|
||||
}catch (Exception e){
|
||||
log.error("minio文件上传失败{}", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//获取路径下的文件夹文件列表
|
||||
public List<FileNode> getFileTree(String directoryName) {
|
||||
List<FileNode> fileNodes = new ArrayList<>();
|
||||
ListObjectsArgs build;
|
||||
|
||||
try {
|
||||
if (StringUtils.isBlank(directoryName)) {
|
||||
build = ListObjectsArgs.builder().bucket(minioProperties.getBucket()).recursive(false).build();
|
||||
} else {
|
||||
build = ListObjectsArgs.builder().bucket(minioProperties.getBucket()).prefix(directoryName+"/").recursive(false).build();
|
||||
}
|
||||
Iterable<Result<Item>> results = minioClient.listObjects(build);
|
||||
for (Result<Item> result : results) {
|
||||
Item item = result.get();
|
||||
String itemName = item.objectName();
|
||||
boolean isDir = item.isDir();
|
||||
String size = FileUtil.readableFileSize(item.size());
|
||||
String relativePath = null;
|
||||
String[] parts = null;
|
||||
if (!StringUtils.isBlank(directoryName)){
|
||||
relativePath = itemName.substring(directoryName.length());
|
||||
parts = relativePath.split("/");
|
||||
}
|
||||
else {
|
||||
parts = itemName.split("/");
|
||||
}
|
||||
String lastModifyTime = null;
|
||||
DateTimeFormatter dateFormat =DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
|
||||
if (!isDir){
|
||||
ZonedDateTime zonedDateTime = item.lastModified();
|
||||
lastModifyTime = zonedDateTime.format(dateFormat);
|
||||
}
|
||||
if (parts.length > 0) {
|
||||
String nodeName = parts[0];
|
||||
int type = isDir ? 0 : 1;
|
||||
itemName= isDir ? itemName.substring(0,itemName.lastIndexOf("/")) : itemName;
|
||||
FileNode node = new FileNode(nodeName, type,size,lastModifyTime,"/"+itemName);
|
||||
if (!fileNodes.contains(node)) {
|
||||
fileNodes.add(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("minio获取树列表失败", e);
|
||||
}
|
||||
return fileNodes;
|
||||
}
|
||||
|
||||
public void readFileToStream(String path, OutputStream stream) {
|
||||
|
||||
try ( GetObjectResponse res = minioClient.getObject(
|
||||
GetObjectArgs.builder().bucket(minioProperties.getBucket()).object(path).build())){
|
||||
res.transferTo(stream);
|
||||
} catch (Exception e) {
|
||||
log.error("minio读取文件失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void download(String path, Path tempDir) {
|
||||
|
||||
try (InputStream inputStream = minioClient.getObject(GetObjectArgs.builder()
|
||||
.bucket(minioProperties.getBucket())
|
||||
.object(path)
|
||||
.build())) {
|
||||
|
||||
// 保存到临时文件夹
|
||||
File tempFile = tempDir.resolve(tempDir+path).toFile();
|
||||
FileUtil.writeFromStream(inputStream,tempFile);
|
||||
}
|
||||
catch (Exception ignored){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 递归方式 计算文件的大小
|
||||
public long getTotalSizeOfFilesInDir(File file) {
|
||||
if (file.isFile()) {
|
||||
return file.length();
|
||||
}
|
||||
|
||||
File[] children = file.listFiles();
|
||||
long total = 0;
|
||||
if (children != null) {
|
||||
|
||||
for (final File child : children) {
|
||||
total += getTotalSizeOfFilesInDir(child);
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
package com.das.modules.fdr.service.impl;
|
||||
|
||||
import com.das.common.constant.FileConstants;
|
||||
import com.das.modules.fdr.domain.FileNode;
|
||||
import com.das.modules.fdr.service.FaultRecorderService;
|
||||
import com.das.modules.fdr.service.MinioViewsServcie;
|
||||
import io.micrometer.common.util.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class FaultRecorderServiceImpl implements FaultRecorderService {
|
||||
|
||||
@Autowired
|
||||
private MinioViewsServcie minioViewsServcie;
|
||||
|
||||
|
||||
@Override
|
||||
public List<FileNode> getDirOrFileList(String name, String startTime, String endTime) {
|
||||
List<FileNode> fileResult = new ArrayList<>();
|
||||
List<String> monthsBetween = getMonthsBetween(startTime, endTime);
|
||||
for (String item : monthsBetween){
|
||||
String directoryName = name + FileConstants.FILE_SEPARATOR + item.substring(0,item.indexOf("-")) + FileConstants.FILE_SEPARATOR + item.substring(item.indexOf("-")+1);
|
||||
List<FileNode> fileTree = minioViewsServcie.getFileTree(directoryName);
|
||||
fileResult.addAll(fileTree);
|
||||
}
|
||||
Comparator<FileNode> fileNodeComparator = Comparator.comparing(FileNode::getLastModified)
|
||||
.thenComparing(FileNode::getName);
|
||||
fileResult.sort(fileNodeComparator);
|
||||
return fileResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String upload(String parent, String folderName, MultipartFile file) {
|
||||
return minioViewsServcie.upload(parent, folderName, file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFileToSteam(String path, OutputStream stream) {
|
||||
minioViewsServcie.readFileToStream(path, stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void download(String path, Path tempDir) {
|
||||
minioViewsServcie.download(path, tempDir);
|
||||
}
|
||||
|
||||
|
||||
private List<String> getMonthsBetween(String startTime, String endTime) {
|
||||
List<String> months = new ArrayList<>();
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||
|
||||
LocalDate start = LocalDate.parse(startTime + "-01", formatter);
|
||||
LocalDate end = LocalDate.parse(endTime + "-01", formatter);
|
||||
|
||||
DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("yyyy-MM");
|
||||
|
||||
while (!start.isAfter(end)) {
|
||||
months.add(start.format(monthFormatter));
|
||||
start = start.plusMonths(1);
|
||||
}
|
||||
return months;
|
||||
}
|
||||
}
|
@ -99,3 +99,9 @@ tdengine:
|
||||
password: taosdata
|
||||
url: jdbc:TAOS-RS://192.168.109.160:6041/das
|
||||
username: root
|
||||
|
||||
minio:
|
||||
url: http://192.168.109.187:9000
|
||||
bucket: das
|
||||
accessKey: das
|
||||
secretKey: zaq12WSX
|
Loading…
Reference in New Issue
Block a user