需求
我遇到的问题不是简单要部署一个新的Nexus私服, 要将旧数据迁移到新的私服中, 而是目前有两个Nexus, 要关掉其中一个, 经过查询,发现基本没有这方面的资料, 大部分都是上传的, 那么既然这样, 我们就基本确定了思路: 先导出到本地, 然后再从本地上传到私服
基本介绍
开始之前先简单介绍一下nexus的基本结构, 以下是Nexus私服的所有库的列表, 我们平时使用maven的setting文件使用的都是maven-public, 但是我们要导出的话是不可以使用,maven-public的,因为它是一个集合(可以注意看一下他得type), 其中集合了多个库, 如果我们要迁移自己的私服一般只需要迁移maven-releases库即可(自定义的除外)
导出到本地
想要将所有的文件都导出到本地, 需要使用到Nexus提供的API服务,可以用这里的服务进行测试,就会返回相应的信息,
分析一下返回的信息
返回的信息中对我们有用的就是items中的downloadUrl, 有了这些我们就可以遍历json逐个下载到本地, 以下是使用java写的一个工具类
/**
* 下载Jar工具类
* 用于从指定的Nexus服务器下载Maven仓库中的Jar包
*/
public class DownloadJar {
// 初始化下载路径
private static final String initPath = "D:\\nexusd\\";
/**
* 递归下载Jar包
*
* @param continuationToken 分页查询的继续令牌
* @throws Exception 可能抛出的异常
*/
public void download(String continuationToken) throws Exception {
// 构建查询参数
Map<String, Object> queryMap = new HashMap<>();
queryMap.put("repository", "maven-releases");
if (StrUtil.isNotEmpty(continuationToken)) {
queryMap.put("continuationToken", continuationToken);
}
// 发送HTTP GET请求获取组件信息
String s = OkHttpRequestUtils.doGet("http://传入自己的下载地址/service/rest/v1/components", queryMap);
// 解析响应JSON,提取items和continuationToken
Map<String, Object> stringStringHashMap = MapperUtils.json2map(s);
List<Map> list = (List) stringStringHashMap.get("items");
if (CollectionUtils.isNotEmpty(list)) {
for (Map map : list) {
List<Map> assets = (List<Map>) map.get("assets");
for (Map dMap : assets) {
String url = String.valueOf(dMap.get("downloadUrl"));
String path = String.valueOf(dMap.get("path"));
System.out.println("开始下载" + url + "到" + initPath + path);
genFile(url, initPath + path);
}
}
// 递归调用,处理下一页
download(stringStringHashMap.get("continuationToken").toString());
}
}
/**
* 根据URL生成文件
*
* @param urlStr 文件的URL地址
* @param path 文件保存的路径
*/
private void genFile(final String urlStr, final String path) {
System.out.println(path);
URL url = null;
try {
url = new URL(urlStr);
String tempFileName = path;
// 先创建文件夹
File t = new File(path);
t.getParentFile().mkdirs();
File temp = new File(tempFileName);
FileUtils.copyURLToFile(url, temp);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String args[]) throws Exception {
// 一开始查询第一页无需传入参数
new DownloadJar().download(null);
}
}
下载完毕
上传到Nexus
我这里的Nexus服务是部署到Linux服务器的, 为了节省上传的时间, 我将本地文件直接上传到了Linux本地再进行的上传操作,因此, 我使用的是sh脚本来完成,原理也很简单, 就是逐个上传的Nexus服务器
#!/bin/bash
# 使用 getopts 处理命令行参数
while getopts ":r:u:p:" opt; do
case $opt in
r)
REPO_URL="$OPTARG" # 设置仓库 URL
;;
u)
USERNAME="$OPTARG" # 设置用户名
;;
p)
PASSWORD="$OPTARG" # 设置密码
;;
\?)
echo "无效的选项: -$OPTARG" >&2 # 处理无效选项
exit 1
;;
:)
echo "选项 -$OPTARG 需要一个参数" >&2 # 处理缺少参数的情况
exit 1
;;
esac
done
# 查找当前目录下的所有文件,排除特定路径和文件
find . -type f \
-not -path './mavenimport.sh*' \
-not -path '*/.*' \
-not -path '*/^archetype-catalog.xml*' \
-not -path '*/^maven-metadata-local*.xml' \
-not -path '*/^maven-metadata-deployment*.xml' \
| sed "s|^\./||" \
| xargs -I '{}' curl -u "$USERNAME:$PASSWORD" -X PUT -v -T {} ${REPO_URL}/{}
# 解释:
# find . -type f: 查找当前目录下的所有文件
# -not -path: 排除特定路径和文件
# sed "s|^\./||": 去掉路径前的 ./
# xargs -I '{}': 将每个文件路径传递给 curl 命令
# curl -u "$USERNAME:$PASSWORD" -X PUT -v -T {}: 使用 curl 命令上传文件
# ${REPO_URL}/{}: 构建完整的上传 URL
将此脚本放在要上传的本地仓库的根目录
记得给文件执行权限
chmod +x upload.sh
运行上传
注意这里的宿主仓库地址一般情况是maven-releases仓库, 或者是自己重新创建的仓库, 复制如下图地址就可以
./upload.sh -u 用户名 -p 密码 -r 宿主仓库地址