package com.fdkankan.fyun.http; import cn.hutool.core.io.FileUtil; import com.alibaba.fastjson.JSONObject; import com.fdkankan.common.constant.ErrorCode; import com.fdkankan.common.exception.BusinessException; import com.fdkankan.common.util.FileUtils; import com.fdkankan.fyun.face.AbstractFYunFileService; import com.fdkankan.fyun.http.config.HttpFyunConfig; import com.fdkankan.fyun.http.entity.Result; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; import org.springframework.web.client.RestTemplate; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.HashMap; import java.util.List; import java.util.Map; @Component @ConditionalOnProperty(name = "fyun.type", havingValue = "https") public class HttpFileService extends AbstractFYunFileService { private Logger log = LoggerFactory.getLogger(this.getClass().getName()); private RestTemplate restTemplate = new RestTemplate(); @Autowired private HttpFyunConfig httpFyunConfig; @Value("${nas.dir.base:/mnt}") private String nasBasePath; @Override public String uploadFile(String bucket, byte[] data, String remoteFilePath) { log.info("fyun http utils upload file by bytes,bucket:{},remoteFilePath:{}", bucket, remoteFilePath); try { // 先将文件保存至本地 String fileName = remoteFilePath.substring(remoteFilePath.lastIndexOf("/") + 1); String localFilePath = nasBasePath + httpFyunConfig.getLocalTempPath() + fileName; log.info("local temp file path:{}", localFilePath); FileUtil.writeBytes(data, localFilePath); uploadFile(bucket, localFilePath, remoteFilePath, null); // FileUtils.deleteFile(nasBasePath + httpFyunConfig.getLocalTempPath() + fileName); } catch (Exception e) { log.error("oss上传文件失败", e); e.printStackTrace(); } return null; } @Override public String uploadFile(String bucket, String filePath, String remoteFilePath) { log.info("fyun http utils upload file by filePath,bucket:{},filePath:{},remoteFilePath:{}", bucket, filePath, remoteFilePath); return uploadFile(bucket, filePath, remoteFilePath, null); } @Override public String uploadFile(String bucket, InputStream inputStream, String remoteFilePath) { log.info("fyun http utils upload file by stream,bucket:{},remoteFilePath:{}", bucket, remoteFilePath); try { // 先将文件保存至本地 String fileName = remoteFilePath.substring(remoteFilePath.lastIndexOf("/") + 1); String localFilePath = nasBasePath + httpFyunConfig.getLocalTempPath() + fileName; FileUtil.writeFromStream(inputStream, localFilePath); uploadFile(bucket, localFilePath, remoteFilePath, null); // FileUtils.deleteFile(nasBasePath + httpFyunConfig.getLocalTempPath() + fileName); } catch (Exception e) { log.error("oss上传文件失败", e); e.printStackTrace(); } return null; } @Override public String uploadFile(String bucket, String filePath, String remoteFilePath, Map headers) { log.info("Fyun httpUtils upload File by filePath with headers , bucket:{},filePath:{},remoteFilePath:{},headers:{}", bucket, filePath, remoteFilePath, headers == null ? "{}" : JSONObject.toJSONString(headers)); try { File file = new File(filePath); if (!file.exists()) { log.error("要上传的文件不存在:" + filePath); return null; } if (filePath.startsWith(nasBasePath)) { filePath = filePath.replace(nasBasePath, ""); }else{ log.info("先将文件{}拷贝至{}", filePath, nasBasePath + filePath); FileUtils.copyFile(filePath, nasBasePath + filePath, true); } if (!remoteFilePath.startsWith(File.separator)) { remoteFilePath = File.separator.concat(remoteFilePath); } Map params = new HashMap<>(); params.put("appName", fYunFileConfig.getKey()); params.put("secret", fYunFileConfig.getSecret()); params.put("fileName", filePath); params.put("targetPath", remoteFilePath); String url = fYunFileConfig.getEndPoint() + httpFyunConfig.getUploadFile(); log.info("url:{},params:{}", url, JSONObject.toJSONString(params)); ResponseEntity responseEntity = restTemplate.postForEntity(url, params, Result.class); log.info("Fyun Http Utils upload,url:{},params:{},结果,{}", url, JSONObject.toJSONString(params), JSONObject.toJSONString(responseEntity.getBody())); if (responseEntity.getStatusCode() != HttpStatus.OK || responseEntity.getBody().getCode() != Result.CODE_SUCCESS) { log.error("Fyun Http Utils upload failed!"); return null; } log.info("文件上传成功,path:{}", filePath); } catch (Exception e) { log.error("oss上传文件失败", e); e.printStackTrace(); } return null; } @Override public String uploadFileByCommand(String bucket, String filePath, String remoteFilePath) { log.info("uploadFileByCommand,bucket:{},filePath:{},remoteFilePath:{}", bucket, filePath, remoteFilePath); if (filePath.substring(filePath.lastIndexOf(File.separator)).contains(".")) { log.info("转上传文件"); return uploadFile(bucket, filePath, remoteFilePath); } // 上传文件夹 Map params = new HashMap<>(); params.put("appName", fYunFileConfig.getKey()); params.put("secret", fYunFileConfig.getSecret()); if (filePath.startsWith(nasBasePath)) { filePath = filePath.replace(nasBasePath, ""); }else{ log.info("先将文件{}拷贝至{}", filePath, nasBasePath + filePath); FileUtils.copyFile(filePath, nasBasePath + filePath, true); } if (filePath.endsWith(File.separator)) { filePath = filePath.substring(0, remoteFilePath.length() - 1); } if (!remoteFilePath.startsWith(File.separator)) { remoteFilePath = File.separator.concat(remoteFilePath); } if (remoteFilePath.endsWith(File.separator)) { remoteFilePath = remoteFilePath.substring(0, remoteFilePath.length() - 1); } params.put("dirName", filePath); params.put("targetPath", remoteFilePath); String url = fYunFileConfig.getEndPoint() + httpFyunConfig.getUploadDir(); log.info("url:{},params:{}", url, JSONObject.toJSONString(params)); ResponseEntity responseEntity = restTemplate.postForEntity(url, params, Result.class); log.info("Fyun Http Utils upload folder,url:{},params:{},结果,{}", url, JSONObject.toJSONString(params), JSONObject.toJSONString(responseEntity.getBody())); if (responseEntity.getStatusCode() != HttpStatus.OK || responseEntity.getBody().getCode() != Result.CODE_SUCCESS) { log.error("Fyun Http Utils upload folder failed!"); } return null; } @Override public void downloadFileByCommand(String bucket, String localPath, String remoteFilePath) { log.info("Fyun http utils download folder by command ,bucket:{},localPath:{},remoteFilePath:{}", bucket, localPath, remoteFilePath); if(remoteFilePath.substring(remoteFilePath.lastIndexOf(File.separator)).contains(".")){ log.info("转下载文件"); downloadFile(remoteFilePath,localPath); } // 下载文件夹 Map params = new HashMap<>(); params.put("appName", fYunFileConfig.getKey()); params.put("secret", fYunFileConfig.getSecret()); if (remoteFilePath.endsWith(File.separator)) { remoteFilePath = remoteFilePath.substring(0, remoteFilePath.length() - 1); } if (!remoteFilePath.startsWith(File.separator)) { remoteFilePath = File.separator + remoteFilePath; } params.put("dirName", remoteFilePath); if (localPath.startsWith(nasBasePath)) { localPath = localPath.replace(nasBasePath, ""); } if (localPath.endsWith(File.separator)) { localPath = localPath.substring(0, localPath.length() - 1); } params.put("targetPath", localPath); String url = fYunFileConfig.getEndPoint() + httpFyunConfig.getDownloadDir(); log.info("url:{},params:{}", url, JSONObject.toJSONString(params)); ResponseEntity responseEntity = restTemplate.postForEntity(url, params, Result.class); log.info("Fyun Http Utils download folder,url:{},params:{},结果,{}", url, JSONObject.toJSONString(params), JSONObject.toJSONString(responseEntity.getBody())); if (responseEntity.getStatusCode() != HttpStatus.OK || responseEntity.getBody().getCode() != Result.CODE_SUCCESS) { log.error("Fyun Http Utils download folder failed!"); }else{ waitFileReadable(nasBasePath+localPath); } } @Override public void deleteFile(String bucket, String remoteFilePath) throws IOException { try { log.info("deleteFile,bucket:{},remoteFilePath:{}", bucket, remoteFilePath); Map params = new HashMap<>(); params.put("appName", fYunFileConfig.getKey()); params.put("secret", fYunFileConfig.getSecret()); if (!remoteFilePath.startsWith(File.separator)) { remoteFilePath = File.separator.concat(remoteFilePath); } params.put("fileName", remoteFilePath); String url = fYunFileConfig.getEndPoint() + httpFyunConfig.getDeleteFile(); log.info("url:{},params:{}", url, JSONObject.toJSONString(params)); ResponseEntity responseEntity = restTemplate.postForEntity(url, params, Result.class); log.info("Fyun Http Utils delete file,url:{},params:{},结果,{}", url, JSONObject.toJSONString(params), JSONObject.toJSONString(responseEntity.getBody())); if (responseEntity.getStatusCode() != HttpStatus.OK || responseEntity.getBody().getCode() != Result.CODE_SUCCESS) { log.error("Fyun Http Utils delete file failed!"); } log.info("文件删除成功,path:{}", remoteFilePath); } catch (Exception e) { log.error("OSS删除文件失败,key=" + remoteFilePath); e.printStackTrace(); } } @Override public void deleteFolder(String bucket, String remoteFolderPath) { try { log.info("delete folder,bucket:{},remoteFilePath:{}", bucket, remoteFolderPath); Map params = new HashMap<>(); params.put("appName", fYunFileConfig.getKey()); params.put("secret", fYunFileConfig.getSecret()); if (!remoteFolderPath.startsWith(File.separator)) { remoteFolderPath = File.separator.concat(remoteFolderPath); } params.put("dirName", remoteFolderPath); String url = fYunFileConfig.getEndPoint() + httpFyunConfig.getDeleteDir(); log.info("url:{},params:{}", url, JSONObject.toJSONString(params)); ResponseEntity responseEntity = restTemplate.postForEntity(url, params, Result.class); log.info("Fyun Http Utils delete folder,url:{},params:{},结果,{}", url, JSONObject.toJSONString(params), JSONObject.toJSONString(responseEntity.getBody())); if (responseEntity.getStatusCode() != HttpStatus.OK || responseEntity.getBody().getCode() != Result.CODE_SUCCESS) { log.error("Fyun Http Utils delete folder failed!"); return; } log.info("文件夹删除成功,path:{}", remoteFolderPath); } catch (Exception e) { log.error("OSS删除文件失败,key=" + remoteFolderPath); e.printStackTrace(); } } @Override public void uploadMulFiles(String bucket, Map filepaths) { try { for (Map.Entry entry : filepaths.entrySet()) { uploadFile(bucket, entry.getKey(), entry.getValue(), null); } } catch (Exception e) { log.error("OSS批量上传文件失败!"); } } @Override public List listRemoteFiles(String bucket, String sourcePath) { try { log.info("list files under path,bucket:{},sourcePath:{}", bucket, sourcePath); Map params = new HashMap<>(); params.put("appName", fYunFileConfig.getKey()); params.put("secret", fYunFileConfig.getSecret()); if (!sourcePath.startsWith(File.separator)) { sourcePath = File.separator.concat(sourcePath); } params.put("dirName", sourcePath); String url = fYunFileConfig.getEndPoint() + httpFyunConfig.getListDir(); log.info("url:{},params:{}", url, JSONObject.toJSONString(params)); ResponseEntity responseEntity = restTemplate.postForEntity(url, params, Result.class); log.info("Fyun Http Utils list dir,url:{},params:{},结果,{}", url, JSONObject.toJSONString(params), JSONObject.toJSONString(responseEntity.getBody())); if (responseEntity.getStatusCode() != HttpStatus.OK || responseEntity.getBody().getCode() != Result.CODE_SUCCESS) { log.error("Fyun Http Utils list dir failed!"); throw new BusinessException(ErrorCode.FAILURE_CODE_3002); } log.info("文件列举成功,path:{}", sourcePath); return JSONObject.parseArray(JSONObject.toJSONString(responseEntity.getBody()),String.class); } catch (Exception e) { log.error("列举文件目录失败,key=" + sourcePath, e); throw new BusinessException(ErrorCode.FAILURE_CODE_3002); } } @Override public void copyFileBetweenBucket(String sourceBucketName, String sourcePath, String targetBucketName, String targetPath) { try { log.info("copy file between bucket,sourceBucket:{},sourcePath:{},targetBucketName,{},targetPath:{}", sourceBucketName, sourcePath, targetBucketName, targetPath); Map params = new HashMap<>(); params.put("appName", fYunFileConfig.getKey()); params.put("secret", fYunFileConfig.getSecret()); if (!targetPath.startsWith(File.separator)) { targetPath = File.separator.concat(targetPath); } if (targetPath.endsWith(File.separator)) { targetPath = targetPath.substring(0, targetPath.length() - 1); } params.put("targetDir", targetPath); String url; if (!sourcePath.startsWith(File.separator)) { sourcePath = File.separator.concat(sourcePath); } if (!sourcePath.substring(sourcePath.lastIndexOf(File.separator)).contains(".")) { if (sourcePath.endsWith(File.separator)) { sourcePath = sourcePath.substring(0, sourcePath.length() - 1); } params.put("dirName", sourcePath); url = fYunFileConfig.getEndPoint() + httpFyunConfig.getCopyDir(); } else { params.put("fileName", sourcePath); url = fYunFileConfig.getEndPoint() + httpFyunConfig.getCopyFile(); } log.info("url:{},params:{}", url, JSONObject.toJSONString(params)); ResponseEntity responseEntity = restTemplate.postForEntity(url, params, Result.class); log.info("Fyun Http Utils copy file or dir,url:{},params:{},结果,{}", url, JSONObject.toJSONString(params), JSONObject.toJSONString(responseEntity.getBody())); if (responseEntity.getStatusCode() != HttpStatus.OK || responseEntity.getBody().getCode() != Result.CODE_SUCCESS) { log.error("Fyun Http Utils copy file or dir failed!"); return; } log.info("文件拷贝成功,path:{}", targetPath); } catch (Exception e) { log.error("列举文件目录失败,key=" + sourcePath); } } @Override public void copyFilesBetweenBucket(String sourceBucketName, String targetBucketName, Map pathMap) { log.info("copy files between bucket,sourceBucket:{},targetBucketName:{},pathMaps:{}", sourceBucketName, targetBucketName, JSONObject.toJSONString(pathMap)); if (ObjectUtils.isEmpty(pathMap)) { return; } try { for (Map.Entry entry : pathMap.entrySet()) { copyFileBetweenBucket(sourceBucketName, entry.getKey(), targetBucketName, entry.getValue()); } } catch (Exception e) { log.error("批量复制文件失败!"); } } @Override public String getFileContent(String bucketName, String remoteFilePath) { try { log.info("获取文件内容:{}", remoteFilePath); if (!remoteFilePath.startsWith(File.separator)) { remoteFilePath = File.separator.concat(remoteFilePath); } // 先将文件下载到本地 String fileName = remoteFilePath.substring(remoteFilePath.lastIndexOf("/") + 1); downloadFile(remoteFilePath, nasBasePath + httpFyunConfig.getLocalTempPath() + fileName); String content = FileUtils.readFile(nasBasePath + httpFyunConfig.getLocalTempPath() + fileName); // FileUtils.deleteFile(nasBasePath + httpFyunConfig.getLocalTempPath() + fileName); return content; } catch (Exception e) { log.error("获取文件内容失败:{}", remoteFilePath); return null; } } @Override public boolean fileExist(String bucket, String objectName) { log.info("file exist check ,bucket:{},remoteFilePath:{}", bucket, objectName); try { Map params = new HashMap<>(); params.put("appName", fYunFileConfig.getKey()); params.put("secret", fYunFileConfig.getSecret()); if (!objectName.startsWith(File.separator)) { objectName = File.separator.concat(objectName); } params.put("fileName", objectName); String url = fYunFileConfig.getEndPoint() + httpFyunConfig.getFileExist(); log.info("url:{},params:{}", url, JSONObject.toJSONString(params)); ResponseEntity responseEntity = restTemplate.postForEntity(url, params, Result.class); log.info("Fyun Http Utils check file exist,url:{},params:{},结果,{}", url, JSONObject.toJSONString(params), JSONObject.toJSONString(responseEntity.getBody())); if (responseEntity.getStatusCode() != HttpStatus.OK || responseEntity.getBody().getCode() != Result.CODE_SUCCESS) { log.error("Fyun Http Utils check file exist failed!"); return false; } return Boolean.parseBoolean(responseEntity.getBody().getData().toString()); } catch (Exception e) { log.error("判断文件是否存在失败:{}", objectName); return false; } } @Override public void downloadFile(String bucket, String remoteFilePath, String localPath) { log.info(" download file ,bucket:{},remoteFilePath:{},localPath:{}", bucket, remoteFilePath, localPath); try { File localFile = new File(localPath); if (!localFile.getParentFile().exists()) { localFile.getParentFile().mkdirs(); } if (localFile.isDirectory()) { String fileName = remoteFilePath.substring(remoteFilePath.lastIndexOf("/") + 1); log.info("未配置文件名,使用默认文件名:{}", fileName); localPath = localPath.concat(File.separator).concat(fileName); } Map params = new HashMap<>(); params.put("appName", fYunFileConfig.getKey()); params.put("secret", fYunFileConfig.getSecret()); if (!remoteFilePath.startsWith(File.separator)) { remoteFilePath = File.separator.concat(remoteFilePath); } params.put("fileName", remoteFilePath); if (new File(localPath).exists()) { FileUtils.deleteFile(localPath); } if (localPath.startsWith(nasBasePath)) { localPath = localPath.replace(nasBasePath, ""); } params.put("targetPath", localPath); String url = fYunFileConfig.getEndPoint() + httpFyunConfig.getDownloadFile(); log.info("url:{},params:{}", url, JSONObject.toJSONString(params)); ResponseEntity responseEntity = restTemplate.postForEntity(url, params, Result.class); log.info("Fyun Http Utils download file,url:{},params:{},结果,{}", url, JSONObject.toJSONString(params), JSONObject.toJSONString(responseEntity.getBody())); if (responseEntity.getStatusCode() != HttpStatus.OK || responseEntity.getBody().getCode() != Result.CODE_SUCCESS) { log.error("Fyun Http Utils download file failed!"); }else{ waitFileReadable(nasBasePath+localPath); } } catch (Throwable throwable) { log.error("文件下载失败:{}", remoteFilePath); throwable.printStackTrace(); } } @Override public URL getPresignedUrl(String bucket, String url) { throw new UnsupportedOperationException("不支持此操作!"); } @Override public long getSubFileNums(String bucket, String url) { return 0; } private void waitFileReadable(String path){ if (new File(path).exists()) { log.info("文件已存在:{}", path); return; } for (long i = 0; i < 36; i++) { log.info("开始第{}次检查文件:{}", i + 1, path); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } if (new File(path).exists()) { return; } } log.error("文件不存在:{}", path); } }