Nexus提供的API
页面访问 {nexus_host}/service/rest/swagger.json
,可以看到Nexus提供的所有API。
接口详情中包含接口的描述、参数、响应状态码等。
根据我的需求,我需要使用两个接口,组件查询接口与组件删除接口,如下图所示:
组件查询:
组件删除:
扫描二维码关注公众号,回复:
15979317 查看本文章
代码如下:
pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.10</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.demo</groupId>
<artifactId>nexus</artifactId>
<version>1.0.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.10.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
package com.demo;
public class Asset {
private String downloadUrl;
private String path;
private String id;
private String repository;
private String format;
private Checksum checksum;
public String getDownloadUrl() {
return downloadUrl;
}
public Asset setDownloadUrl(String downloadUrl) {
this.downloadUrl = downloadUrl;
return this;
}
public String getPath() {
return path;
}
public Asset setPath(String path) {
this.path = path;
return this;
}
public String getId() {
return id;
}
public Asset setId(String id) {
this.id = id;
return this;
}
public String getRepository() {
return repository;
}
public Asset setRepository(String repository) {
this.repository = repository;
return this;
}
public String getFormat() {
return format;
}
public Asset setFormat(String format) {
this.format = format;
return this;
}
public Checksum getChecksum() {
return checksum;
}
public Asset setChecksum(Checksum checksum) {
this.checksum = checksum;
return this;
}
}
package com.demo;
public class Checksum {
private String sha1;
private String md5;
public String getSha1() {
return sha1;
}
public Checksum setSha1(String sha1) {
this.sha1 = sha1;
return this;
}
public String getMd5() {
return md5;
}
public Checksum setMd5(String md5) {
this.md5 = md5;
return this;
}
}
package com.demo;
import java.util.List;
public class Module {
private String id;
private String repository;
private String format;
private String group;
private String name;
private String version;
private List<Asset> assets;
public String getId() {
return id;
}
public Module setId(String id) {
this.id = id;
return this;
}
public String getRepository() {
return repository;
}
public Module setRepository(String repository) {
this.repository = repository;
return this;
}
public String getFormat() {
return format;
}
public Module setFormat(String format) {
this.format = format;
return this;
}
public String getGroup() {
return group;
}
public Module setGroup(String group) {
this.group = group;
return this;
}
public String getName() {
return name;
}
public Module setName(String name) {
this.name = name;
return this;
}
public String getVersion() {
return version;
}
public Module setVersion(String version) {
this.version = version;
return this;
}
public List<Asset> getAssets() {
return assets;
}
public Module setAssets(List<Asset> assets) {
this.assets = assets;
return this;
}
}
package com.demo;
public class Service {
private String groupId;
private String artifactId;
public String getGroupId() {
return groupId;
}
public Service setGroupId(String groupId) {
this.groupId = groupId;
return this;
}
public String getArtifactId() {
return artifactId;
}
public Service setArtifactId(String artifactId) {
this.artifactId = artifactId;
return this;
}
}
package com.demo;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class Clean {
private static final OkHttpClient HTTP_CLIENT = new OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS).readTimeout(10, TimeUnit.SECONDS).build();
private static final Logger LOGGER = LoggerFactory.getLogger(Clean.class);
private static final String NEXUS_HOST = "http://xxx.com";
// 账户需要有查询和删除权限
private static final String NEXUS_USERNAME = "admin";
private static final String NEXUS_PASSWORD = "admin";
private static final String NEXUS_REPOSITORY = "maven-snapshots";
public static void main(String[] args) {
// 需要删除的组件坐标信息
List<Service> serviceList = new ArrayList<>();
serviceList.add(new Service().setGroupId("com.huobi.bit.ops.service").setArtifactId("huobi-bit-ops-service"));
// 需要删除的组件版本
// List<String> versionList = new ArrayList<>();
// versionList.add("1.0-SNAPSHOT");
for(Service service : serviceList) {
List<Module> moduleList = new ArrayList<>();
search(NEXUS_HOST, NEXUS_USERNAME, NEXUS_PASSWORD, NEXUS_REPOSITORY, service.getGroupId(), service.getArtifactId(), null, moduleList);
for (Module module : moduleList) {
// if (versionList.contains(module.getVersion())) {
if (module.getVersion().startsWith("1.0-")) {
// 版本匹配执行删除
delete(NEXUS_HOST, NEXUS_USERNAME, NEXUS_PASSWORD, module);
}
}
}
}
private static void search(String host, String username, String password, String repository, String groupId, String artifactId, String token, List<Module> list) {
String url = String.format("%s/service/rest/v1/search?repository=%s&group=%s&name=%s", host, repository, groupId, artifactId);
if (StringUtils.hasText(token)) {
// 拼接上次查询返回的continuationToken,查询下一页
url = url + "&continuationToken=" + token;
}
Request request = new Request.Builder()
.addHeader("Authorization", getToken(username, password))
.addHeader("Connection", "keep-alive")
.url(url)
.get()
.build();
Call call = HTTP_CLIENT.newCall(request);
try (Response response = call.execute()) {
if (response.code() == 200 && response.body() != null) {
JSONObject jsonObject = JSONObject.parseObject(response.body().string());
List<Module> result = jsonObject.getObject("items", new TypeReference<List<Module>>() {
});
if (CollectionUtils.isEmpty(result)) {
return;
}
list.addAll(result);
String conToken = jsonObject.getString("continuationToken");
if (!StringUtils.hasText(conToken) || "null".equals(conToken)) {
return;
}
// 携带continuationToken递归查询下一页
search(host, username, password, repository, groupId, artifactId, conToken, list);
} else {
LOGGER.error("组件搜索出错,http响应:{}", response.body());
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void delete(String host, String username, String password, Module module) {
LOGGER.info("执行删除: {}", module.getVersion());
String url = String.format("%s/service/rest/v1/components/%s", host, module.getId());
Request request = new Request.Builder()
.addHeader("Authorization", getToken(username, password))
.addHeader("Connection", "keep-alive")
.url(url)
.delete()
.build();
Call call = HTTP_CLIENT.newCall(request);
try (Response response = call.execute()) {
if (response.code() == 204) {
LOGGER.info("删除成功!");
} else {
LOGGER.error("删除失败! 状态码:{}", response.code());
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static String getToken(String name, String password) {
String authString = name + ":" + password;
byte[] authEncBytes = Base64.getEncoder().encode(authString.getBytes(StandardCharsets.UTF_8));
return "Basic " + new String(authEncBytes);
}
}