|
@@ -1,282 +0,0 @@
|
|
|
-package cn.com.qmth.examcloud.exchange.inner.service.upyun;
|
|
|
-
|
|
|
-import java.io.File;
|
|
|
-import java.io.FileInputStream;
|
|
|
-import java.io.FileNotFoundException;
|
|
|
-import java.io.InputStream;
|
|
|
-import java.security.InvalidKeyException;
|
|
|
-import java.security.NoSuchAlgorithmException;
|
|
|
-import java.security.SignatureException;
|
|
|
-import java.text.SimpleDateFormat;
|
|
|
-import java.util.Base64;
|
|
|
-import java.util.Calendar;
|
|
|
-import java.util.Locale;
|
|
|
-import java.util.TimeZone;
|
|
|
-
|
|
|
-import javax.crypto.Mac;
|
|
|
-import javax.crypto.spec.SecretKeySpec;
|
|
|
-
|
|
|
-import org.apache.commons.compress.utils.IOUtils;
|
|
|
-import org.apache.commons.lang3.StringUtils;
|
|
|
-import org.apache.http.HttpStatus;
|
|
|
-import org.apache.http.client.config.RequestConfig;
|
|
|
-import org.apache.http.client.methods.CloseableHttpResponse;
|
|
|
-import org.apache.http.client.methods.HttpDelete;
|
|
|
-import org.apache.http.client.methods.HttpPut;
|
|
|
-import org.apache.http.entity.InputStreamEntity;
|
|
|
-import org.apache.http.impl.client.CloseableHttpClient;
|
|
|
-import org.apache.http.impl.client.HttpClients;
|
|
|
-import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
|
|
-import org.apache.http.util.EntityUtils;
|
|
|
-
|
|
|
-import cn.com.qmth.examcloud.commons.exception.ExamCloudRuntimeException;
|
|
|
-import cn.com.qmth.examcloud.commons.exception.StatusException;
|
|
|
-import cn.com.qmth.examcloud.commons.logging.ExamCloudLog;
|
|
|
-import cn.com.qmth.examcloud.commons.logging.ExamCloudLogFactory;
|
|
|
-import cn.com.qmth.examcloud.commons.util.MD5;
|
|
|
-
|
|
|
-/**
|
|
|
- * upyun client
|
|
|
- *
|
|
|
- * @author WANGWEI
|
|
|
- * @date 2018年11月21日
|
|
|
- * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
|
|
|
- */
|
|
|
-public class UpYunClient {
|
|
|
-
|
|
|
- protected ExamCloudLog log = ExamCloudLogFactory.getLog(this.getClass());
|
|
|
-
|
|
|
- /**
|
|
|
- * 空间名
|
|
|
- */
|
|
|
- protected String bucketName = null;
|
|
|
-
|
|
|
- /**
|
|
|
- * 操作员名
|
|
|
- */
|
|
|
- protected String userName = null;
|
|
|
-
|
|
|
- /**
|
|
|
- * 操作员密码
|
|
|
- */
|
|
|
- protected String password = null;
|
|
|
-
|
|
|
- protected String md5Password = null;
|
|
|
-
|
|
|
- public static final String API_DOMAIN = "v0.api.upyun.com";
|
|
|
-
|
|
|
- private static final String MKDIR = "mkdir";
|
|
|
-
|
|
|
- private final String METHOD_PUT = "PUT";
|
|
|
-
|
|
|
- private final String METHOD_DELETE = "DELETE";
|
|
|
-
|
|
|
- private final String DATE = "Date";
|
|
|
-
|
|
|
- private final String AUTHORIZATION = "Authorization";
|
|
|
-
|
|
|
- private final String SEPARATOR = "/";
|
|
|
-
|
|
|
- private CloseableHttpClient httpclient;
|
|
|
-
|
|
|
- private RequestConfig requestConfig;
|
|
|
-
|
|
|
- private String domain;
|
|
|
-
|
|
|
- /**
|
|
|
- * 构造函数
|
|
|
- *
|
|
|
- * @param bucketName
|
|
|
- * @param userName
|
|
|
- * @param password
|
|
|
- */
|
|
|
- public UpYunClient(String bucketName, String userName, String password, String domain) {
|
|
|
- PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
|
|
|
- cm.setMaxTotal(1000);
|
|
|
- httpclient = HttpClients.custom().setConnectionManager(cm).disableAutomaticRetries()
|
|
|
- .build();
|
|
|
- requestConfig = RequestConfig.custom().setConnectionRequestTimeout(10000)
|
|
|
- .setSocketTimeout(10000).setConnectTimeout(10000).build();
|
|
|
-
|
|
|
- this.bucketName = bucketName;
|
|
|
- this.userName = userName;
|
|
|
- this.password = password;
|
|
|
- this.domain = domain;
|
|
|
- this.md5Password = MD5.encrypt32(password);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 上传文件
|
|
|
- *
|
|
|
- * @author WANGWEI
|
|
|
- * @param filePath
|
|
|
- * @param file
|
|
|
- * @return
|
|
|
- */
|
|
|
- public UpYunPathInfo writeFile(String filePath, File file) {
|
|
|
-
|
|
|
- InputStream in = null;
|
|
|
- try {
|
|
|
- in = new FileInputStream(file);
|
|
|
- return writeFile(filePath, in);
|
|
|
- } catch (FileNotFoundException e) {
|
|
|
- throw new ExamCloudRuntimeException(e);
|
|
|
- } finally {
|
|
|
- IOUtils.closeQuietly(in);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 上传文件
|
|
|
- *
|
|
|
- * @author WANGWEI
|
|
|
- * @param filePath
|
|
|
- * @param in
|
|
|
- * @return
|
|
|
- */
|
|
|
- public UpYunPathInfo writeFile(String filePath, InputStream in) {
|
|
|
- String path = formatPath(filePath);
|
|
|
- String url = "https://" + API_DOMAIN + path;
|
|
|
-
|
|
|
- HttpPut httpPut = new HttpPut(url);
|
|
|
- httpPut.setConfig(this.requestConfig);
|
|
|
- CloseableHttpResponse response = null;
|
|
|
-
|
|
|
- long s = System.currentTimeMillis();
|
|
|
- try {
|
|
|
-
|
|
|
- String date = getDate();
|
|
|
- String authorization = sign(userName, md5Password, METHOD_PUT, path, date, "", "");
|
|
|
- httpPut.addHeader(AUTHORIZATION, authorization);
|
|
|
- httpPut.addHeader(DATE, date);
|
|
|
- httpPut.addHeader(MKDIR, "true");
|
|
|
-
|
|
|
- httpPut.setEntity(new InputStreamEntity(in));
|
|
|
- response = httpclient.execute(httpPut);
|
|
|
- int statusCode = response.getStatusLine().getStatusCode();
|
|
|
-
|
|
|
- if (HttpStatus.SC_OK != statusCode) {
|
|
|
- log.error("[upyun error] " + EntityUtils.toString(response.getEntity(), "UTF-8"));
|
|
|
- throw new StatusException("100001", "[upyun]. fail to write file");
|
|
|
- }
|
|
|
- } catch (StatusException e) {
|
|
|
- throw e;
|
|
|
- } catch (Exception e) {
|
|
|
- throw new ExamCloudRuntimeException(e);
|
|
|
- } finally {
|
|
|
- IOUtils.closeQuietly(in);
|
|
|
- IOUtils.closeQuietly(response);
|
|
|
- httpPut.releaseConnection();
|
|
|
- }
|
|
|
-
|
|
|
- if (log.isDebugEnabled()) {
|
|
|
- log.debug("[upyun]. write file. path=" + path + "; cost "
|
|
|
- + (System.currentTimeMillis() - s) + " ms.");
|
|
|
- }
|
|
|
-
|
|
|
- String fileUrl = this.domain + filePath;
|
|
|
- return new UpYunPathInfo(fileUrl, filePath);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 删除文件
|
|
|
- *
|
|
|
- * @author WANGWEI
|
|
|
- * @param filePath
|
|
|
- * @return
|
|
|
- */
|
|
|
- public void deleteFile(String filePath) {
|
|
|
- String path = formatPath(filePath);
|
|
|
- String url = "https://" + API_DOMAIN + path;
|
|
|
-
|
|
|
- HttpDelete httpDelete = new HttpDelete(url);
|
|
|
- httpDelete.setConfig(this.requestConfig);
|
|
|
- CloseableHttpResponse response = null;
|
|
|
-
|
|
|
- long s = System.currentTimeMillis();
|
|
|
- try {
|
|
|
- String date = getDate();
|
|
|
- String authorization = sign(userName, md5Password, METHOD_DELETE, path, date, "", "");
|
|
|
- httpDelete.addHeader(AUTHORIZATION, authorization);
|
|
|
- httpDelete.addHeader(DATE, date);
|
|
|
-
|
|
|
- response = httpclient.execute(httpDelete);
|
|
|
- int statusCode = response.getStatusLine().getStatusCode();
|
|
|
-
|
|
|
- if (HttpStatus.SC_OK != statusCode) {
|
|
|
- log.error("[upyun error] " + EntityUtils.toString(response.getEntity(), "UTF-8"));
|
|
|
- throw new StatusException("100002", "[upyun]. fail to delete file");
|
|
|
- }
|
|
|
- } catch (StatusException e) {
|
|
|
- throw e;
|
|
|
- } catch (Exception e) {
|
|
|
- throw new ExamCloudRuntimeException(e);
|
|
|
- } finally {
|
|
|
- IOUtils.closeQuietly(response);
|
|
|
- httpDelete.releaseConnection();
|
|
|
- }
|
|
|
-
|
|
|
- if (log.isDebugEnabled()) {
|
|
|
- log.debug("[upyun]. delete file. path=" + path + "; cost "
|
|
|
- + (System.currentTimeMillis() - s) + " ms.");
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 格式化路径参数
|
|
|
- * <p>
|
|
|
- * 最终构成的格式:"/空间名/文件路径"
|
|
|
- *
|
|
|
- * @param path
|
|
|
- * 目录路径或文件路径
|
|
|
- * @return 格式化后的路径
|
|
|
- */
|
|
|
- private String formatPath(String path) {
|
|
|
-
|
|
|
- if (StringUtils.isNotBlank(path)) {
|
|
|
-
|
|
|
- // 去除前后的空格
|
|
|
- path = path.trim();
|
|
|
-
|
|
|
- // 确保路径以"/"开头
|
|
|
- if (!path.startsWith(SEPARATOR)) {
|
|
|
- return SEPARATOR + bucketName + SEPARATOR + path;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return SEPARATOR + bucketName + path;
|
|
|
- }
|
|
|
-
|
|
|
- private String getDate() {
|
|
|
- Calendar calendar = Calendar.getInstance();
|
|
|
- SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z",
|
|
|
- Locale.US);
|
|
|
- dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
|
|
|
- return dateFormat.format(calendar.getTime());
|
|
|
- }
|
|
|
-
|
|
|
- private byte[] hashHmac(String data, String key)
|
|
|
- throws SignatureException, NoSuchAlgorithmException, InvalidKeyException {
|
|
|
- SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
|
|
|
- Mac mac = Mac.getInstance("HmacSHA1");
|
|
|
- mac.init(signingKey);
|
|
|
- return mac.doFinal(data.getBytes());
|
|
|
- }
|
|
|
-
|
|
|
- private String sign(String key, String secret, String method, String uri, String date,
|
|
|
- String policy, String md5) throws Exception {
|
|
|
- String value = method + "&" + uri + "&" + date;
|
|
|
- if (policy != null && policy.length() > 0) {
|
|
|
- value = value + "&" + policy;
|
|
|
- }
|
|
|
-
|
|
|
- if (md5 != null && md5.length() > 0) {
|
|
|
- value = value + "&" + md5;
|
|
|
- }
|
|
|
- byte[] hmac = hashHmac(value, secret);
|
|
|
- String sign = Base64.getEncoder().encodeToString(hmac);
|
|
|
- return "UPYUN " + key + ":" + sign;
|
|
|
- }
|
|
|
-
|
|
|
-}
|