feat(制品库功能开发): 针对各种格式的制品上传开发接口(开发Maven制品上传接口)

完善Maven制品上传接口逻辑:
1. 上传时将制品文件记录及文件标识保存到数据库中(若生成POM同时保存POM记录,POM文件标识后续从Nexus下载)
2. 制品文件保存接口将先在组织下根据制品库名称和制品文件名称检查制品文件是否已存在,若存在则更新该制品文件记录,若不存在则创建该制品文件记录
This commit is contained in:
OTTO 2024-07-03 10:12:20 +08:00
parent 85cfa9b7bc
commit 32aec72065
7 changed files with 144 additions and 178 deletions

View File

@ -1,9 +1,10 @@
package com.microservices.pms.productLibrary.domain;
import com.microservices.common.core.annotation.Excel;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.microservices.common.core.web.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 制品库-制品对象 pms_product_library_component
@ -11,6 +12,8 @@ import org.apache.commons.lang3.builder.ToStringStyle;
* @author otto
* @date 2024-06-27
*/
@Data
@ApiModel("制品对象")
public class PmsProductLibraryComponent extends BaseEntity {
private static final long serialVersionUID = 1L;
@ -22,228 +25,93 @@ public class PmsProductLibraryComponent extends BaseEntity {
/**
* 制品标识
*/
@Excel(name = "制品标识")
@ApiModelProperty(value = "制品标识")
private String identifier;
/**
* 制品路径
*/
@Excel(name = "制品路径")
@ApiModelProperty(value = "制品路径")
private String path;
/**
* 制品所在组
*/
@Excel(name = "制品所在组")
@ApiModelProperty(value = "制品所在组")
private String group;
/**
* 制品名称
*/
@Excel(name = "制品名称")
@ApiModelProperty(value = "制品名称")
private String name;
/**
* 制品库名称
*/
@Excel(name = "制品库名称")
@ApiModelProperty(value = "制品库名称")
private String repoName;
/**
* 制品版本
*/
@Excel(name = "制品版本")
@ApiModelProperty(value = "制品版本")
private String version;
/**
* 制品文件Id
*/
@Excel(name = "制品文件Id")
@ApiModelProperty(value = "制品文件Id")
private String fileIdentifier;
/**
* 关联组织ID
*/
@Excel(name = "关联组织ID")
@ApiModelProperty(value = "关联组织ID")
private Long deptId;
/**
* 关联企业ID
*/
@Excel(name = "关联企业ID")
@ApiModelProperty(value = "关联企业ID")
private Long pmsEnterpriseId;
/**
* 关联企业ID
*/
@ApiModelProperty(value = "关联企业标识", hidden = true)
private String pmsEnterpriseIdentifier;
/**
* 删除标志0代表存在 2代表删除
*/
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String delFlag;
/**
* 其他属性JSON字符串
*/
@Excel(name = "其他属性", readConverterExp = "J=SON字符串")
@ApiModelProperty(value = "其他属性JSON字符串")
private String attributes;
/**
* 预留字段1
*/
@Excel(name = "预留字段1")
@ApiModelProperty(value = "预留字段1")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String reservedField1;
/**
* 预留字段2
*/
@Excel(name = "预留字段2")
@ApiModelProperty(value = "预留字段2")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String reservedField2;
/**
* 预留字段3
*/
@Excel(name = "预留字段3")
@ApiModelProperty(value = "预留字段3")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String reservedField3;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getIdentifier() {
return identifier;
}
public void setIdentifier(String identifier) {
this.identifier = identifier;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRepoName() {
return repoName;
}
public void setRepoName(String repoName) {
this.repoName = repoName;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getFileIdentifier() {
return fileIdentifier;
}
public void setFileIdentifier(String fileIdentifier) {
this.fileIdentifier = fileIdentifier;
}
public Long getDeptId() {
return deptId;
}
public void setDeptId(Long deptId) {
this.deptId = deptId;
}
public Long getPmsEnterpriseId() {
return pmsEnterpriseId;
}
public void setPmsEnterpriseId(Long pmsEnterpriseId) {
this.pmsEnterpriseId = pmsEnterpriseId;
}
public String getDelFlag() {
return delFlag;
}
public void setDelFlag(String delFlag) {
this.delFlag = delFlag;
}
public String getAttributes() {
return attributes;
}
public void setAttributes(String attributes) {
this.attributes = attributes;
}
public String getReservedField1() {
return reservedField1;
}
public void setReservedField1(String reservedField1) {
this.reservedField1 = reservedField1;
}
public String getReservedField2() {
return reservedField2;
}
public void setReservedField2(String reservedField2) {
this.reservedField2 = reservedField2;
}
public String getReservedField3() {
return reservedField3;
}
public void setReservedField3(String reservedField3) {
this.reservedField3 = reservedField3;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("identifier", getIdentifier())
.append("path", getPath())
.append("group", getGroup())
.append("name", getName())
.append("repoName", getRepoName())
.append("version", getVersion())
.append("fileIdentifier", getFileIdentifier())
.append("deptId", getDeptId())
.append("pmsEnterpriseId", getPmsEnterpriseId())
.append("updateTime", getUpdateTime())
.append("updateBy", getUpdateBy())
.append("createTime", getCreateTime())
.append("createBy", getCreateBy())
.append("delFlag", getDelFlag())
.append("attributes", getAttributes())
.append("reservedField1", getReservedField1())
.append("reservedField2", getReservedField2())
.append("reservedField3", getReservedField3())
.toString();
}
}

View File

@ -67,6 +67,7 @@ public class PmsProductLibraryRepositories extends BaseEntity {
/**
* 删除标志0代表存在 2代表删除
*/
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String delFlag;
/**

View File

@ -23,4 +23,12 @@ public class AssetMavenInputVo {
@ApiModelProperty(value = "文件标识")
@NotBlank(message = "制品文件标识不能为空")
private String fileIdentifier;
public String getComponentAssetName(ComponentMavenInputVo componentMavenInputVo) {
return String.format("%s-%s-%s.%s",
componentMavenInputVo.getArtifactId(),
componentMavenInputVo.getVersion(),
classifier,
extension);
}
}

View File

@ -1,5 +1,6 @@
package com.microservices.pms.productLibrary.domain.vo;
import com.microservices.pms.productLibrary.domain.PmsProductLibraryComponent;
import com.microservices.pms.productLibrary.domain.PmsProductLibraryRepositories;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ -47,4 +48,19 @@ public class ComponentMavenInputVo {
repoName
);
}
public String getPomComponentName() {
return String.format("%s-%s.pom", artifactId, version);
}
public PmsProductLibraryComponent toPmsProductLibraryComponent(String name) {
PmsProductLibraryComponent pmsProductLibraryComponent = new PmsProductLibraryComponent();
pmsProductLibraryComponent.setRepoName(repoName);
pmsProductLibraryComponent.setName(name);
pmsProductLibraryComponent.setPath(String.format("%s/%s/%s/%s", groupId, artifactId, version, name));
pmsProductLibraryComponent.setGroup(groupId);
pmsProductLibraryComponent.setVersion(version);
pmsProductLibraryComponent.setPmsEnterpriseIdentifier(enterpriseIdentifier);
return pmsProductLibraryComponent;
}
}

View File

@ -2,6 +2,7 @@ package com.microservices.pms.productLibrary.mapper;
import com.microservices.pms.productLibrary.domain.PmsProductLibraryComponent;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@ -60,4 +61,14 @@ public interface PmsProductLibraryComponentMapper {
* @return 结果
*/
public int deletePmsProductLibraryComponentByIds(Long[] ids);
/**
* 在组织下根据制品库名称和制品文件名称查找制品文件
*
* @param name 制品文件名称
* @param repoName 制品库名称
* @param pmsEnterpriseId 组织Id
* @return 制品文件
*/
PmsProductLibraryComponent selectPmsProductLibraryComponentByNameAndRepoName(@Param("name") String name, @Param("repoName") String repoName, @Param("pmsEnterpriseId") Long pmsEnterpriseId);
}

View File

@ -4,6 +4,9 @@ import com.alibaba.fastjson2.JSONObject;
import com.microservices.common.core.constant.SecurityConstants;
import com.microservices.common.core.exception.ServiceException;
import com.microservices.common.core.utils.DateUtils;
import com.microservices.common.security.utils.SecurityUtils;
import com.microservices.pms.enterprise.domain.PmsEnterprise;
import com.microservices.pms.enterprise.service.IPmsEnterpriseService;
import com.microservices.pms.productLibrary.domain.PmsProductLibraryComponent;
import com.microservices.pms.productLibrary.domain.PmsProductLibraryRepositories;
import com.microservices.pms.productLibrary.domain.ProductLibraryRepositoriesFormatEnum;
@ -23,8 +26,8 @@ import org.springframework.stereotype.Service;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* 制品库-制品Service业务层处理
@ -42,6 +45,8 @@ public class PmsProductLibraryComponentServiceImpl implements IPmsProductLibrary
private RemoteFileService fileService;
@Autowired
private NexusRequestHelper nexusRequestHelper;
@Autowired
private IPmsEnterpriseService pmsEnterpriseService;
/**
* 查询制品库-制品
@ -73,8 +78,25 @@ public class PmsProductLibraryComponentServiceImpl implements IPmsProductLibrary
*/
@Override
public int insertPmsProductLibraryComponent(PmsProductLibraryComponent pmsProductLibraryComponent) {
pmsProductLibraryComponent.setCreateTime(DateUtils.getNowDate());
return pmsProductLibraryComponentMapper.insertPmsProductLibraryComponent(pmsProductLibraryComponent);
PmsEnterprise pmsEnterprise = pmsEnterpriseService.selectPmsEnterpriseByIdentifier(pmsProductLibraryComponent.getPmsEnterpriseIdentifier());
PmsProductLibraryComponent oldPmsProductLibraryComponent =
pmsProductLibraryComponentMapper.selectPmsProductLibraryComponentByNameAndRepoName(
pmsProductLibraryComponent.getName(),
pmsProductLibraryComponent.getRepoName(),
pmsEnterprise.getId());
// 当制品文件不存在时新增该文件
if (oldPmsProductLibraryComponent == null) {
pmsProductLibraryComponent.setCreateBy(SecurityUtils.getUsername());
pmsProductLibraryComponent.setCreateTime(DateUtils.getNowDate());
pmsProductLibraryComponent.setPmsEnterpriseId(pmsEnterprise.getId());
pmsProductLibraryComponent.setDeptId(pmsEnterprise.getDeptId());
return pmsProductLibraryComponentMapper.insertPmsProductLibraryComponent(pmsProductLibraryComponent);
}
// 当制品文件已存在时更新该文件
pmsProductLibraryComponent.setId(oldPmsProductLibraryComponent.getId());
pmsProductLibraryComponent.setUpdateBy(SecurityUtils.getUsername());
pmsProductLibraryComponent.setUpdateTime(DateUtils.getNowDate());
return pmsProductLibraryComponentMapper.updatePmsProductLibraryComponent(pmsProductLibraryComponent);
}
/**
@ -113,6 +135,8 @@ public class PmsProductLibraryComponentServiceImpl implements IPmsProductLibrary
@Override
public Boolean insertMavenComponent(ComponentMavenInputVo componentMavenInputVo) {
// 构建制品列表用于数据库记录
List<PmsProductLibraryComponent> pmsProductLibraryComponents = new ArrayList<>();
PmsProductLibraryRepositories repo =
pmsProductLibraryRepositoriesService.selectPmsProductLibraryRepositoriesByName(
componentMavenInputVo.getEnterpriseIdentifier(),
@ -129,11 +153,23 @@ public class PmsProductLibraryComponentServiceImpl implements IPmsProductLibrary
addTextBody(builder, "maven2.artifactId", componentMavenInputVo.getArtifactId());
addTextBody(builder, "maven2.version", componentMavenInputVo.getVersion());
addTextBody(builder, "maven2.generate-pom", String.valueOf(componentMavenInputVo.getGeneratePom()));
// 若需要生成Pom则存在一个Pom的制品文件
if (componentMavenInputVo.getGeneratePom()) {
pmsProductLibraryComponents.add(componentMavenInputVo.toPmsProductLibraryComponent(componentMavenInputVo.getPomComponentName()));
}
addTextBody(builder, "maven2.packaging", componentMavenInputVo.getPackaging());
List<AssetMavenInputVo> assetMavenInputVoList = componentMavenInputVo.getAssetList();
for (int i = 0; i < assetMavenInputVoList.size(); i++) {
AssetMavenInputVo assetMavenInputVo = assetMavenInputVoList.get(i);
String componentAssetName = assetMavenInputVo.getComponentAssetName(componentMavenInputVo);
if (pmsProductLibraryComponents.stream().anyMatch(x -> componentAssetName.equals(x.getName()))) {
throw new ServiceException("不允许上传重复的制品文件(制品文件名称(%s)", componentAssetName);
}
// 将制品的每一个文件创建对应的记录
PmsProductLibraryComponent componentAsset = componentMavenInputVo.toPmsProductLibraryComponent(componentAssetName);
componentAsset.setFileIdentifier(assetMavenInputVo.getFileIdentifier());
pmsProductLibraryComponents.add(componentAsset);
addTextBody(builder, String.format("maven2.asset%d.extension", i + 1), assetMavenInputVo.getExtension());
addTextBody(builder, String.format("maven2.asset%d.classifier", i + 1), assetMavenInputVo.getClassifier());
File file = FeignUtils.getReturnData(
@ -143,11 +179,14 @@ public class PmsProductLibraryComponentServiceImpl implements IPmsProductLibrary
}
JSONObject bodyLog = JSONObject.from(componentMavenInputVo);
nexusRequestHelper.doRequest(NexusRequestUrl.UPLOAD_COMPONENTS(componentMavenInputVo.getNexusRepoName()), builder.build(), bodyLog);
// 上传成功后删除该文件
String fileIdentifiers = assetMavenInputVoList.stream().map(AssetMavenInputVo::getFileIdentifier).collect(Collectors.joining());
return FeignUtils.getReturnData(
fileService.deleteFileByIdentifiers(fileIdentifiers, SecurityConstants.INNER)
);
// 数据库中插入制品文件记录
int success = 0;
for (int i = 0; i < pmsProductLibraryComponents.size(); i++) {
PmsProductLibraryComponent pmsProductLibraryComponent = pmsProductLibraryComponents.get(i);
success += insertPmsProductLibraryComponent(pmsProductLibraryComponent);
pmsProductLibraryComponents.set(i, pmsProductLibraryComponent);
}
return success > 0;
}
private void addTextBody(MultipartEntityBuilder builder, String key, String value) {

View File

@ -27,8 +27,25 @@
</resultMap>
<sql id="selectPmsProductLibraryComponentVo">
select id, identifier, path,
group, name, repo_name, version, file_identifier, dept_id, pms_enterprise_id, update_time, update_by, create_time, create_by, del_flag, attributes, reserved_field_1, reserved_field_2, reserved_field_3
select id,
identifier,
path,
`group`,
name,
repo_name,
version,
file_identifier,
dept_id,
pms_enterprise_id,
update_time,
update_by,
create_time,
create_by,
del_flag,
attributes,
reserved_field_1,
reserved_field_2,
reserved_field_3
from pms_product_library_component
</sql>
@ -37,9 +54,9 @@
<include refid="selectPmsProductLibraryComponentVo"/>
<where>
<if test="identifier != null and identifier != ''">and identifier = #{identifier}</if>
<if test="path != null and path != ''">and path = #{path}</if>
<if test="group != null and group != ''">and group = #{group}</if>
<if test="name != null and name != ''">and name like concat('%', #{name}, '%')</if>
<if test="path != null and path != ''">and `path` = #{path}</if>
<if test="group != null and group != ''">and `group` = #{group}</if>
<if test="name != null and name != ''">and `name` like concat('%', #{name}, '%')</if>
<if test="repoName != null and repoName != ''">and repo_name like concat('%', #{repoName}, '%')</if>
<if test="version != null and version != ''">and version = #{version}</if>
<if test="fileIdentifier != null and fileIdentifier != ''">and file_identifier = #{fileIdentifier}</if>
@ -56,15 +73,21 @@
<include refid="selectPmsProductLibraryComponentVo"/>
where id = #{id}
</select>
<select id="selectPmsProductLibraryComponentByNameAndRepoName" resultMap="PmsProductLibraryComponentResult">
<include refid="selectPmsProductLibraryComponentVo"/>
where name = #{name}
and repo_name = #{repoName}
and pms_enterprise_id = #{pmsEnterpriseId}
</select>
<insert id="insertPmsProductLibraryComponent" parameterType="PmsProductLibraryComponent" useGeneratedKeys="true"
keyProperty="id">
insert into pms_product_library_component
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="identifier != null and identifier != ''">identifier,</if>
<if test="path != null and path != ''">path,</if>
<if test="group != null and group != ''">group,</if>
<if test="name != null and name != ''">name,</if>
<if test="path != null and path != ''">`path`,</if>
<if test="group != null and group != ''">`group`,</if>
<if test="name != null and name != ''">`name`,</if>
<if test="repoName != null and repoName != ''">repo_name,</if>
<if test="version != null">version,</if>
<if test="fileIdentifier != null">file_identifier,</if>
@ -107,7 +130,7 @@
<trim prefix="SET" suffixOverrides=",">
<if test="identifier != null and identifier != ''">identifier = #{identifier},</if>
<if test="path != null and path != ''">path = #{path},</if>
<if test="group != null and group != ''">group = #{group},</if>
<if test="group != null and group != ''">`group` = #{group},</if>
<if test="name != null and name != ''">name = #{name},</if>
<if test="repoName != null and repoName != ''">repo_name = #{repoName},</if>
<if test="version != null">version = #{version},</if>