
com.taobao.hsf.standalone.sar.HSFSarUtil Maven / Gradle / Ivy
The newest version!
package com.taobao.hsf.standalone.sar;
import com.taobao.hsf.standalone.util.Constant;
import com.taobao.middleware.pandora.toolkit.SarExtractor;
import com.taobao.middleware.pandora.toolkit.SarFetcher;
import com.taobao.middleware.pandora.toolkit.commons.HttpUtils;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
/**
* 处理Sar包的工具类
*
* @author [email protected]
* @author xiaozi.ll
*/
public class HSFSarUtil {
private static final String libPath = "lib";
/**
* public可被外部取代默认值
*/
public static String[] jarFolders = new String[] { libPath };
public static URL[] listSarJar(String sarPath) {
if (sarPath == null) {
throw new IllegalArgumentException("sarPath[" + sarPath + "] can't be null");
}
File sarDir = new File(sarPath);
if (!sarDir.exists() | !sarDir.isDirectory()) {
throw new IllegalArgumentException("sarPath[" + sarPath + "] must be a folder");
}
URL[] allUrls = null;
for (String jarFolder : jarFolders) {
URL[] urls = addJar(sarPath, jarFolder);
if (urls == null) {
continue;
}
if (allUrls == null) {
allUrls = urls;
continue;
}
URL[] tempAllUrls = allUrls;
allUrls = new URL[tempAllUrls.length + urls.length];
System.arraycopy(tempAllUrls, 0, allUrls, 0, tempAllUrls.length);
System.arraycopy(urls, 0, allUrls, tempAllUrls.length, urls.length);
}
return allUrls;
}
private static URL[] addJar(String hsfJarRootPath, String jarFolder) {
File folder = new File(hsfJarRootPath + File.separator + jarFolder);
if (!folder.exists() | !folder.isDirectory()) {
return null;
}
File[] jarList = folder.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
if (name.endsWith(".jar") | name.endsWith(".jar.plugin")) return true;
return false;
}
});
URL[] urls = new URL[jarList.length];
for (int i = 0; i < jarList.length; i++) {
try {
URL jarUrl = new URL("file:" + jarList[i].getAbsoluteFile());
urls[i] = jarUrl;
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
return urls;
}
/**
*
* 在指定的路径(destSarPath)下准备指定版本(sarVersion)的sar包。准备sar包的过程在多进程条件下会加锁,
* 保证检测sar包的过程不被其他进程准备sar包的过程干扰。
*
* 1. 若destSarPath下已存在taobao-hsf.sar目录,则使用;
* 2. 若destSarPath下已存在taobao-hsf.tgz文件,则解压为taobao-hsf.sar,并使用;
* 3. 若destSarPath下不存在taobao-hsf.sar或taobao-hsf.tgz,则:
* - 下载指定版本(sarVersion)的taobao-hsf.tgz
* - 解压taobao-hsf.tgz为taobao-hsf.sar,并使用。
*
*
* @param destSarPath 指定的sar包父路径,不可为空
* @param sarVersion 指定的sar包版本号,不可为空
* @return 成功准备sar包,返回taobao-hsf.sar的路径;否则,返回null
* @throws IOException
*/
public static String prepareHSFSar(String destSarPath, String sarVersion) throws IOException {
if (sarVersion == null) {
throw new IllegalArgumentException("parameter 'sarVersion' can not be null.");
}
if (destSarPath == null || destSarPath.trim().length() == 0) {
throw new IllegalArgumentException("parameter 'destSarPath' can not be null or empty.");
}
// 创建准备sar包的base path
File basePath = new File(destSarPath);
if (!basePath.exists() || !basePath.isDirectory()) {
if (!basePath.mkdirs()) {
throw new RuntimeException("Can not create base path of taobao-hsf.sar: " + destSarPath);
}
}
// 创建锁文件,通过对文件加独占锁以保证多进程条件下准备sar包的正确性
File lockFile = new File(basePath, "prepare-sar.lock");
lockFile.createNewFile();
FileChannel channel = null;
FileLock lock = null;
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(lockFile,"rw");
channel = raf.getChannel();
lock = channel.lock(); // 阻塞锁
// 检查taobao-hsf.sar
File localSarFile = new File(basePath, "taobao-hsf.sar");
if (localSarFile.exists() && localSarFile.isDirectory()) {
return localSarFile.getCanonicalPath();
}
// 检查taobao-hsf.tgz
File localTgzFile = new File(basePath, "taobao-hsf.tgz");
if (localTgzFile.exists() && localTgzFile.isFile()) {
File decompressedSar = SarExtractor.decompressSar(localTgzFile);
if (decompressedSar != null) {
return decompressedSar.getCanonicalPath();
}
}
// 决策、获取Sar包版本号
String originSarVersion = sarVersion;
sarVersion = decideSarVersion(sarVersion);
if (sarVersion == null) {
throw new RuntimeException("Can not decide a valid sar version to use.");
}
// 下载taobao-hsf.tgz,会删除当前路径下已经存在taobao-hsf.tgz文件
File tgzSarFile = downloadTgzSar(sarVersion, basePath);
if (tgzSarFile == null) {
// 若sar包版本号以数字开头,则替换版本号中的 “.” 为 “_”,再次尝试下载
String nonDotSarVersion = convertSarVersion(sarVersion);
if (!nonDotSarVersion.equals(sarVersion)) {
System.out.println("[HSF-LightApi] >> Can not download taobao-hsf.tgz by sarVersion[" + sarVersion
+ "]. Try to download taobao-hsf.tgz by sarVersion[" + nonDotSarVersion + "]");
tgzSarFile = downloadTgzSar(nonDotSarVersion, basePath);
}
if (tgzSarFile == null) {
throw new RuntimeException("Download taobao-hsf.tgz failed. sarVersion may not be right: "
+ originSarVersion);
}
}
// 解压taobao-hsf.tgz,会删除当前路径下已经存在taobao-hsf.sar目录
File sarFile = SarExtractor.decompressSar(tgzSarFile);
if (sarFile != null && sarFile.exists() && sarFile.isDirectory()) {
return sarFile.getCanonicalPath();
} else {
throw new RuntimeException("Decompress taobao-hsf.tgz failed.");
}
} finally {
if (lock != null) {
lock.release();
}
if (channel != null) {
channel.close();
}
if (raf != null) {
raf.close();
}
}
}
/**
* 决策、获取Sar包版本号,决策版本号的优先级为:
* 参数sarVersion > Constant.version > -Dsar.version > 推荐版本
*
* @param sarVersion
* @return 返回按决策顺序首先得到的非空版本号,若整个过程都未获取非空版本号,则返回null
*/
private static String decideSarVersion(String sarVersion) {
String decidedVersion = sarVersion;
if (decidedVersion == null || decidedVersion.trim().length() == 0) {
decidedVersion = Constant.version.get();
if (decidedVersion.equals(Constant.NO_VALUE)) {
decidedVersion = SarFetcher.getDefaultSarVersion();
}
}
return decidedVersion;
}
/**
* 若sarVersion以数字开头,则替换sarVersion中的“.”为“_”并返回;否则直接返回sarVersion。
*
* @param sarVersion
* @return
*/
private static String convertSarVersion(String sarVersion) {
if (sarVersion != null && Character.isDigit(sarVersion.charAt(0))) {
return sarVersion.replace(".", "_");
}
return sarVersion;
}
/**
* 下载taobao-hsf.tgz,会从多处尝试:
*
* - 若perferDownloadUrl被设置,则尝试从用户自定义URL下载
* - 若从自定义URL未下载到sar包,则尝试从Pandora运维系统下载
* - 若从Pandora运维系统未下载到sar包,则尝试从老版HSF软件中心下载
*
*
* @param sarVersion
* @param basePath
* @return 下载成功,返回taobao-hsf.tgz的File对象;否则,返回null
*/
private static File downloadTgzSar(String sarVersion, File basePath) {
// 删除已存在的taobao-hsf.tgz
File exsitedTgzFile = new File(basePath, "taobao-hsf.tgz");
if (exsitedTgzFile.exists() && exsitedTgzFile.isFile()) {
exsitedTgzFile.delete();
}
// 1) 尝试从用户自定义URL下载
File tgzSarFile = downloadPreferSar(basePath);
if (tgzSarFile != null) {
System.out.println("[HSF-LightApi] >> Downloaded taobao-hsf.tgz from " + Constant.perferDownloadUrl.get());
return tgzSarFile;
}
// 2) 尝试从Pandora运维系统下载
tgzSarFile = SarFetcher.downloadSar(sarVersion, basePath.getPath());
if (tgzSarFile != null) {
System.out.println("[HSF-LightApi] >> Downloaded taobao-hsf.tgz from pandora-web");
return tgzSarFile;
}
// 3) 尝试从老版HSF软件中心下载
tgzSarFile = downloadOldSar(sarVersion, basePath);
if (tgzSarFile != null) {
System.out.println("[HSF-LightApi] >> Downloaded taobao-hsf.tgz from " + Constant.HSF_DOWNLOAD_SAR_URL);
return tgzSarFile;
}
return null;
}
/**
* 尝试从用户自定义URL下载sar包,最终的下载链接:perferDownloadUrl/sarVersion/taobao-hsf.tgz
*
* @param baseFile
* @return 下载成功,返回taobao-hsf.tgz的File对象;否则,返回null
*/
private static File downloadPreferSar(File baseFile) {
String preferDownloadUrl = Constant.perferDownloadUrl.get();
if (Constant.NO_VALUE.equals(preferDownloadUrl)) {
return null;
}
File tgzFile = new File(baseFile, "taobao-hsf.tgz");
String downloadUrl = preferDownloadUrl + "/taobao-hsf.tgz";
if (HttpUtils.downloadFile(downloadUrl, tgzFile.getPath())) {
if(tgzFile.exists() && tgzFile.isFile() && tgzFile.length() > Constant.MIN_TGZ_SAR_SIZE) {
return tgzFile;
}
}
return null;
}
/**
* 尝试从HSF老的软件中心下载sar包
*
* @param sarVersion
* @param baseFile
* @return 下载成功,返回taobao-hsf.tgz的File对象;否则,返回null
*/
private static File downloadOldSar(String sarVersion, File baseFile) {
File tgzFile = new File(baseFile, "taobao-hsf.tgz");
String downloadUrl = Constant.HSF_DOWNLOAD_SAR_URL + sarVersion + "/taobao-hsf.tgz";
if (HttpUtils.downloadFile(downloadUrl, tgzFile.getPath())) {
if(tgzFile.exists() && tgzFile.isFile() && tgzFile.length() > Constant.MIN_TGZ_SAR_SIZE) {
return tgzFile;
}
}
return null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy