feat(制品库功能开发): 产品库中关键制品获取接口开发(排除自动生成的无关制品)

1. 当制品库为Maven时,需排除自动生成的制品数据
- 调用Nexus通用查询接口(/service/extdirect),通过层级浏览获取制品数据列表
- 遍历制品数据列表,当类型为asset时,检查数据库中是否存在该制品数据记录,若不存在则不返回该条数据
2. 当制品库为Docker时,仅需展示Docker镜像名称及版本(标签)
- 调用Nexus制品列表获取接口(/service/rest/v1/components),基于分页Token循环遍历所有docker制品列表
- 将docker制品转换为Nexus制品查询结果数据对象,同时添加到响应列表中
- 构建Nexus制品查询结果对象进行数据返回
This commit is contained in:
OTTO 2024-07-09 16:40:05 +08:00
parent d8eb141a3f
commit aaeb4eec7d
12 changed files with 202 additions and 16 deletions

View File

@ -37,7 +37,7 @@ public class PmsProductLibraryComponentController extends BaseController {
@GetMapping("/list")
@ApiOperation(value = "查询制品列表")
public AjaxResult list(@PathVariable String enterpriseIdentifier, @Valid ComponentSearchVo componentSearchVo) {
NexusComponentResultVo<NexusResultDataVo> result =
NexusComponentResultVo<List<NexusResultDataVo>> result =
pmsProductLibraryComponentService.selectPmsProductLibraryComponentList(enterpriseIdentifier, componentSearchVo, false);
return success(result);
}

View File

@ -111,7 +111,7 @@ public class PmsProductLibraryController extends BaseController {
@GetMapping("/component/list")
@ApiOperation(value = "产品库查询制品列表")
public AjaxResult list(@PathVariable String enterpriseIdentifier, @Valid ComponentSearchVo componentSearchVo) {
NexusComponentResultVo<NexusResultDataVo> result =
NexusComponentResultVo<List<NexusResultDataVo>> result =
pmsProductLibraryComponentService.selectPmsProductLibraryComponentList(enterpriseIdentifier, componentSearchVo, true);
return success(result);
}
@ -217,4 +217,17 @@ public class PmsProductLibraryController extends BaseController {
pmsProductLibraryComponentService.deleteFolderByNode(enterpriseIdentifier, componentSearchVo, true);
return success(result);
}
/**
* 获取制品库下关键制品排除自动生成的无关制品
*/
// @RequiresPermissions("pms:pmsProductLibraryComponent:list")
@GetMapping("/keyComponent/list")
@ApiOperation(value = "制品库查询关键制品列表")
public AjaxResult keyComponentList(@PathVariable String enterpriseIdentifier, @Valid ComponentSearchVo componentSearchVo) {
NexusComponentResultVo<List<NexusResultDataVo>> result =
pmsProductLibraryComponentService.selectPmsProductLibraryKeyComponentList(enterpriseIdentifier, componentSearchVo);
return success(result);
}
}

View File

@ -8,7 +8,7 @@ import java.util.List;
* @author OTTO
*/
@Data
public class NexusMavenAssetListVo {
public class NexusComponentAndAssetListVo<T> {
/**
* 分页Token
*/
@ -16,6 +16,6 @@ public class NexusMavenAssetListVo {
/**
* 制品文件列表
*/
private List<NexusMavenAssetVo> items;
private List<T> items;
}

View File

@ -42,4 +42,5 @@ public class NexusComponentResultVo<T> {
*/
@ApiModelProperty(value = "结果成功状态")
private NexusComponentResultStateVo<T> result;
}

View File

@ -0,0 +1,51 @@
package com.microservices.pms.productLibrary.domain.vo;
import com.alibaba.fastjson2.JSONArray;
import com.microservices.common.core.utils.StringUtils;
import com.microservices.common.core.utils.sign.Base64;
import lombok.Data;
/**
* @author OTTO
*/
@Data
public class NexusDockerComponentVo {
/**
* 制品标识
*/
private String id;
/**
* 制品名称
*/
private String name;
/**
* 制品库名称
*/
private String repository;
/**
* 格式
*/
private String format;
/**
* 版本
*/
private String version;
/**
* maven对象属性
*/
private JSONArray assets;
public NexusResultDataVo toNexusResultDataVo() {
NexusResultDataVo target = new NexusResultDataVo();
target.setId(name);
target.setText(String.format("%s:%s", name, version));
String composeId = Base64.base64ToDecoderString(id);
if (StringUtils.isNotEmpty(composeId)) {
String[] composeIds = composeId.split(":");
target.setComponentId(composeIds[1]);
}
target.setLeaf(true);
return target;
}
}

View File

@ -70,7 +70,7 @@ public interface PmsProductLibraryComponentMapper {
* @param pmsEnterpriseId 组织Id
* @return 制品文件
*/
PmsProductLibraryComponent selectPmsProductLibraryComponentByNameAndRepoName(@Param("name") String name, @Param("repoId") Long repoId, @Param("pmsEnterpriseId") Long pmsEnterpriseId);
PmsProductLibraryComponent selectPmsProductLibraryComponentByNameAndRepoId(@Param("name") String name, @Param("repoId") Long repoId, @Param("pmsEnterpriseId") Long pmsEnterpriseId);
/**
* 根据制品文件路径查找制品

View File

@ -28,7 +28,7 @@ public interface IPmsProductLibraryComponentService {
* @param isProduct
* @return 制品库-制品集合
*/
public NexusComponentResultVo<NexusResultDataVo> selectPmsProductLibraryComponentList(String enterpriseIdentifier, ComponentSearchVo componentSearchVo, boolean isProduct);
public NexusComponentResultVo<List<NexusResultDataVo>> selectPmsProductLibraryComponentList(String enterpriseIdentifier, ComponentSearchVo componentSearchVo, boolean isProduct);
/**
* 新增制品库-制品
@ -89,7 +89,7 @@ public interface IPmsProductLibraryComponentService {
* @param enterpriseIdentifier 企业标识
* @param repoName 制品库名称
* @param assetId 制品文件标识
* @param isProduct
* @param isProduct 是否产品库
* @return 制品文件详情
*/
NexusComponentResultVo<NexusAssetResultDataVo> getAssetDetailByAssetId(String enterpriseIdentifier, String repoName, String assetId, boolean isProduct);
@ -100,7 +100,7 @@ public interface IPmsProductLibraryComponentService {
* @param enterpriseIdentifier 企业标识
* @param repoName 制品库名称
* @param componentId 制品标识
* @param isProduct
* @param isProduct 是否产品库
* @return 制品详情
*/
NexusComponentResultVo<NexusComponentResultDataVo> getComponentDetailByComponentId(String enterpriseIdentifier, String repoName, String componentId, boolean isProduct);
@ -110,7 +110,7 @@ public interface IPmsProductLibraryComponentService {
*
* @param enterpriseIdentifier 企业标识
* @param componentSearchVo 文件夹查询条件
* @param isProduct
* @param isProduct 是否产品库
* @return 能否删除状态
*/
NexusComponentResultVo<Boolean> getCanDeleteFolderByNode(String enterpriseIdentifier, ComponentSearchVo componentSearchVo, boolean isProduct);
@ -125,7 +125,7 @@ public interface IPmsProductLibraryComponentService {
* @param enterpriseIdentifier 企业标识
* @param repoName 制品库名称
* @param assetId 制品文件
* @param isProduct
* @param isProduct 是否产品库
* @return 删除文件列表
*/
NexusComponentResultVo<List<String>> deleteAssetByAssetId(String enterpriseIdentifier, String repoName, String assetId, boolean isProduct);
@ -133,4 +133,13 @@ public interface IPmsProductLibraryComponentService {
NexusComponentResultVo<List<String>> deleteComponentByComponentId(String enterpriseIdentifier, String repoName, String componentId, boolean isProduct);
NexusComponentResultVo<Object> deleteFolderByNode(String enterpriseIdentifier, ComponentSearchVo componentSearchVo, boolean isProduct);
/**
* 查询关键制品列表
*
* @param enterpriseIdentifier 企业标识
* @param componentSearchVo 查询条件
* @return 制品列表
*/
NexusComponentResultVo<List<NexusResultDataVo>> selectPmsProductLibraryKeyComponentList(String enterpriseIdentifier, ComponentSearchVo componentSearchVo);
}

View File

@ -3,7 +3,7 @@ package com.microservices.pms.productLibrary.service.impl;
import com.microservices.common.core.utils.StringUtils;
import com.microservices.pms.productLibrary.domain.PmsProductLibraryComponent;
import com.microservices.pms.productLibrary.domain.PmsProductLibraryRepositories;
import com.microservices.pms.productLibrary.domain.vo.NexusMavenAssetListVo;
import com.microservices.pms.productLibrary.domain.vo.NexusComponentAndAssetListVo;
import com.microservices.pms.productLibrary.domain.vo.NexusMavenAssetVo;
import com.microservices.pms.productLibrary.service.IPmsProductLibraryAsyncService;
import com.microservices.pms.productLibrary.service.IPmsProductLibraryComponentService;
@ -33,11 +33,12 @@ public class PmsProductLibraryAsyncServiceImpl implements IPmsProductLibraryAsyn
CustomExecutorFactory.threadPoolExecutor.execute(() -> {
// 遍历制品库制品文件列表根据数据库制品文件记录获取对应的制品标识
boolean isContinuationGet = true;
NexusMavenAssetListVo assetListVo = new NexusMavenAssetListVo();
NexusComponentAndAssetListVo<NexusMavenAssetVo> assetListVo = new NexusComponentAndAssetListVo<>();
while (isContinuationGet) {
assetListVo = nexusRequestHelper.doRequestToJavaObject(
NexusRequestUrl.GET_ASSETS(repo.getNexusRepositoriesName(), assetListVo.getContinuationToken()),
NexusMavenAssetListVo.class);
NexusComponentAndAssetListVo.class,
NexusMavenAssetVo.class);
List<NexusMavenAssetVo> assetList = assetListVo.getItems();
if (pmsProductLibraryComponents.stream().allMatch(x -> StringUtils.isNotEmpty(x.getIdentifier()))) {
break;

View File

@ -84,7 +84,7 @@ public class PmsProductLibraryComponentServiceImpl implements IPmsProductLibrary
* @return 制品库-制品
*/
@Override
public NexusComponentResultVo<NexusResultDataVo> selectPmsProductLibraryComponentList(String enterpriseIdentifier, ComponentSearchVo componentSearchVo, boolean isProduct) {
public NexusComponentResultVo<List<NexusResultDataVo>> selectPmsProductLibraryComponentList(String enterpriseIdentifier, ComponentSearchVo componentSearchVo, boolean isProduct) {
PmsProductLibraryRepositories pmsProductLibraryRepositories =
getPmsProductLibraryRepositoriesByIsProduct(isProduct, enterpriseIdentifier, componentSearchVo.getRepositoryName());
componentSearchVo.setRepositoryName(pmsProductLibraryRepositories.getNexusRepositoriesName(isProduct));
@ -98,6 +98,94 @@ public class PmsProductLibraryComponentServiceImpl implements IPmsProductLibrary
);
}
private NexusComponentResultVo<List<NexusResultDataVo>> buildDockerResultVo(List<NexusResultDataVo> data) {
NexusComponentResultVo<List<NexusResultDataVo>> target = new NexusComponentResultVo<>();
target.setAction("coreui_Browse");
target.setMethod("read");
target.setTid(1);
target.setType("rpc");
NexusComponentResultStateVo<List<NexusResultDataVo>> nexusComponentResultStateVo = new NexusComponentResultStateVo<List<NexusResultDataVo>>();
nexusComponentResultStateVo.setData(data);
nexusComponentResultStateVo.setSuccess(true);
target.setResult(nexusComponentResultStateVo);
return target;
}
@Override
public NexusComponentResultVo<List<NexusResultDataVo>> selectPmsProductLibraryKeyComponentList(String enterpriseIdentifier, ComponentSearchVo componentSearchVo) {
PmsProductLibraryRepositories repo =
getPmsProductLibraryRepositoriesByIsProduct(false, enterpriseIdentifier, componentSearchVo.getRepositoryName());
componentSearchVo.setRepositoryName(repo.getNexusRepositoriesName(false));
// Docker类型调用Nexus获取制品列表接口获取
if (ProductLibraryRepositoriesFormatEnum.DOCKER.getKey().equals(repo.getFormat())) {
List<NexusResultDataVo> keyNexusResultDataVoList = new ArrayList<>();
// 需循环遍历获取所有镜像列表
boolean isAll = false;
// Nexus分页Token
String continuationToken = null;
while (!isAll) {
NexusComponentAndAssetListVo<NexusDockerComponentVo> assetListVo = nexusRequestHelper.doRequestToJavaObject(
NexusRequestUrl.GET_COMPONENTS(repo.getNexusRepositoriesName(), continuationToken),
NexusComponentAndAssetListVo.class,
NexusDockerComponentVo.class);
if (assetListVo != null) {
if (StringUtils.isEmpty(assetListVo.getContinuationToken())) {
isAll = true;
} else {
continuationToken = assetListVo.getContinuationToken();
}
for (NexusDockerComponentVo nexusDockerComponentVo : assetListVo.getItems()) {
NexusResultDataVo nexusResultDataVo = nexusDockerComponentVo.toNexusResultDataVo();
keyNexusResultDataVoList.add(nexusResultDataVo);
}
} else {
isAll = true;
}
}
return buildDockerResultVo(keyNexusResultDataVoList);
} else {
NexusComponentSearchVo<ComponentSearchVo> nexusComponentSearchVo = NexusComponentSearchVo.toRead(componentSearchVo, nexusRequestHelper.getNexusTid());
NexusComponentResultVo<List<NexusResultDataVo>> assetResultDataVo = nexusRequestHelper.doRequestToJavaObjectList(
NexusRequestUrl.DO_OPERATION(),
JSONObject.from(nexusComponentSearchVo),
NexusComponentResultVo.class,
NexusResultDataVo.class
);
if (assetResultDataVo != null && assetResultDataVo.getResult() != null) {
NexusComponentResultStateVo<List<NexusResultDataVo>> nexusComponentResultStateVo = assetResultDataVo.getResult();
if (nexusComponentResultStateVo.getSuccess()) {
List<NexusResultDataVo> nexusResultDataVoList = nexusComponentResultStateVo.getData();
// 当制品库为Maven时需排除自动生成的制品数据
if (ProductLibraryRepositoriesFormatEnum.MAVEN.getKey().equals(repo.getFormat())) {
List<NexusResultDataVo> keyNexusResultDataVoList = new ArrayList<>();
for (NexusResultDataVo nexusResultDataVo : nexusResultDataVoList) {
// 当类型为asset时需检查数据库是否存在记录若存在则返回
if ("asset".equals(nexusResultDataVo.getType())) {
PmsProductLibraryComponent pmsProductLibraryComponent =
pmsProductLibraryComponentMapper.selectPmsProductLibraryComponentByPath(
nexusResultDataVo.getId(),
repo.getId(),
repo.getPmsEnterpriseId()
);
if (pmsProductLibraryComponent != null) {
keyNexusResultDataVoList.add(nexusResultDataVo);
}
} else {
keyNexusResultDataVoList.add(nexusResultDataVo);
}
}
nexusComponentResultStateVo.setData(keyNexusResultDataVoList);
assetResultDataVo.setResult(nexusComponentResultStateVo);
}
}
}
return assetResultDataVo;
}
}
@Override
public NexusComponentResultVo<NexusAssetResultDataVo> getAssetDetailByAssetId(String enterpriseIdentifier, String repoName, String assetId, boolean isProduct) {

View File

@ -246,6 +246,14 @@ public class NexusRequestHelper {
return res.toJavaObject(tClass);
}
public <T> T doRequestToJavaObject(NexusRequestUrl nexusRequestUrl, Type ownerClass, Type rawClass) {
JSONObject res = (JSONObject) doRequestToObject(nexusRequestUrl, null, null);
if (res == null) {
return null;
}
return JSONObject.parseObject(res.toJSONString(), buildType(ownerClass, rawClass));
}
private static Type buildType(Type... types) {
ParameterizedTypeImpl beforeType = null;
if (types != null && types.length > 0) {

View File

@ -96,7 +96,7 @@ public class NexusRequestUrl {
}
/**
* 获取制品库中制品列表
* 获取制品库中制品文件列表
*
* @param nexusRepoName 制品库名称
* @param continuationToken 分页标记
@ -110,6 +110,21 @@ public class NexusRequestUrl {
return getNexusRequestUrl(RequestType.GET, path);
}
/**
* 获取制品库中制品列表
*
* @param nexusRepoName 制品库名称
* @param continuationToken 分页标记
* @return 请求地址
*/
public static NexusRequestUrl GET_COMPONENTS(String nexusRepoName, String continuationToken) {
String path = String.format("/service/rest/v1/components?repository=%s", nexusRepoName);
if (StringUtils.isNotEmpty(continuationToken)) {
path = path + "&continuationToken=" + continuationToken;
}
return getNexusRequestUrl(RequestType.GET, path);
}
public enum RequestType {
POST,
POST_FILE,

View File

@ -73,7 +73,7 @@
<include refid="selectPmsProductLibraryComponentVo"/>
where id = #{id}
</select>
<select id="selectPmsProductLibraryComponentByNameAndRepoName" resultMap="PmsProductLibraryComponentResult">
<select id="selectPmsProductLibraryComponentByNameAndRepoId" resultMap="PmsProductLibraryComponentResult">
<include refid="selectPmsProductLibraryComponentVo"/>
where name = #{name}
and repo_id = #{repoId}