Merge remote-tracking branch 'origin/dev-1.1' into dev-1.1
This commit is contained in:
@@ -2,24 +2,21 @@ package net.geedge.asw.module.app.controller;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.log.Log;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import net.geedge.asw.common.util.ASWException;
|
||||
import net.geedge.asw.common.util.R;
|
||||
import net.geedge.asw.common.util.RCode;
|
||||
import net.geedge.asw.common.util.T;
|
||||
import net.geedge.asw.module.app.entity.*;
|
||||
import net.geedge.asw.module.app.service.*;
|
||||
import net.geedge.asw.module.app.entity.ApplicationEntity;
|
||||
import net.geedge.asw.module.app.service.IApplicationService;
|
||||
import net.geedge.asw.module.workspace.entity.WorkspaceEntity;
|
||||
import net.geedge.asw.module.workspace.service.IWorkspaceService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -36,7 +33,7 @@ public class ApplicationController {
|
||||
@Autowired
|
||||
private IApplicationService applicationService;
|
||||
|
||||
@Autowired
|
||||
/*@Autowired
|
||||
private IApplicationSignatureService signatureService;
|
||||
|
||||
@Autowired
|
||||
@@ -267,11 +264,11 @@ public class ApplicationController {
|
||||
.eq(ApplicationHrefEntity::getApplicationId, applicationId)
|
||||
.in(ApplicationHrefEntity::getId, T.ListUtil.of(ids)));
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
}*/
|
||||
|
||||
@PostMapping("/import")
|
||||
public R importApplication(@RequestParam String workspaceId,
|
||||
public synchronized R importApplication(@RequestParam String workspaceId,
|
||||
@RequestParam String branchName,
|
||||
@RequestParam(defaultValue = "tsg2402") String format,
|
||||
@RequestParam(value = "files") List<MultipartFile> fileList) {
|
||||
// validate
|
||||
@@ -292,25 +289,36 @@ public class ApplicationController {
|
||||
throw new ASWException(RCode.APP_IMPORT_FILE_FORMAT_ERROR);
|
||||
}
|
||||
|
||||
// 名称重复校验
|
||||
List<Object> applicationList = dataList.stream()
|
||||
.map(entries -> entries.getJSONArray("applications"))
|
||||
.flatMap(Collection::stream)
|
||||
.collect(Collectors.toList());
|
||||
long distinctNameCount = applicationList.stream()
|
||||
.map(obj -> ((JSONObject) obj).getStr("app_name"))
|
||||
.distinct()
|
||||
.count();
|
||||
long size = applicationList.size();
|
||||
if (T.ObjectUtil.notEqual(size, distinctNameCount)) {
|
||||
throw new ASWException(RCode.APP_DUPLICATE_RECORD);
|
||||
}
|
||||
|
||||
// import
|
||||
List<ApplicationEntity> entityList = applicationService.importAppByFormat(workspaceId, format, dataList);
|
||||
List<ApplicationEntity> entityList = applicationService.importAppByFormat(workspaceId, branchName, format, dataList);
|
||||
List<Map<String, String>> records = entityList.stream()
|
||||
.map(entity -> Map.of("id", entity.getId()))
|
||||
.map(entity -> Map.of("name", entity.getName()))
|
||||
.collect(Collectors.toList());
|
||||
return R.ok().putData("records", records);
|
||||
}
|
||||
|
||||
@GetMapping("/export")
|
||||
public void exportApplication(@RequestParam String workspaceId,
|
||||
@RequestParam String ids,
|
||||
@RequestParam String branchName,
|
||||
@RequestParam String names,
|
||||
@RequestParam(defaultValue = "tsg2402") String format,
|
||||
HttpServletResponse response) throws IOException {
|
||||
// validate
|
||||
List<ApplicationEntity> appList = applicationService.list(
|
||||
new LambdaQueryWrapper<ApplicationEntity>()
|
||||
.eq(ApplicationEntity::getWorkspaceId, workspaceId)
|
||||
.in(ApplicationEntity::getId, T.ListUtil.of(ids.split(",")))
|
||||
);
|
||||
List<ApplicationEntity> appList = applicationService.queryList(workspaceId, branchName, T.StrUtil.splitToArray(names, ","));
|
||||
T.VerifyUtil.is(appList).notEmpty(RCode.APP_NOT_EXIST);
|
||||
|
||||
// format
|
||||
|
||||
@@ -1,67 +1,26 @@
|
||||
package net.geedge.asw.module.app.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import lombok.Data;
|
||||
import net.geedge.asw.module.sys.entity.SysUserEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@TableName(value = "application", autoResultMap = true)
|
||||
public class ApplicationEntity {
|
||||
|
||||
@TableId(type = IdType.ASSIGN_UUID)
|
||||
private String id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String tags;
|
||||
|
||||
private String packageName;
|
||||
|
||||
private String longName;
|
||||
private String developer;
|
||||
private String website;
|
||||
private String description;
|
||||
|
||||
private String provider;
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private Object packageName;
|
||||
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private Object properties;
|
||||
|
||||
private String status;
|
||||
|
||||
private String description;
|
||||
|
||||
private Long createTimestamp;
|
||||
|
||||
private Long updateTimestamp;
|
||||
|
||||
private String createUserId;
|
||||
|
||||
private String updateUserId;
|
||||
|
||||
private String workspaceId;
|
||||
|
||||
private Integer opVersion;
|
||||
|
||||
@TableField(exist = false)
|
||||
private SysUserEntity createUser;
|
||||
|
||||
@TableField(exist = false)
|
||||
private SysUserEntity updateUser;
|
||||
|
||||
@TableField(exist = false)
|
||||
private ApplicationSignatureEntity signature;
|
||||
|
||||
@TableField(exist = false)
|
||||
private ApplicationNoteEntity note;
|
||||
|
||||
@TableField(exist = false)
|
||||
private List<ApplicationAttachmentEntity> attatchments;
|
||||
|
||||
@TableField(exist = false)
|
||||
private List<ApplicationHrefEntity> hrefs;
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private Object signature;
|
||||
|
||||
}
|
||||
@@ -15,7 +15,8 @@ public class ApplicationMergeEntity {
|
||||
private String id;
|
||||
private String sourceBranch;
|
||||
private String targetBranch;
|
||||
private String commitId;
|
||||
private String startCommitId;
|
||||
private String endCommitId;
|
||||
private String title;
|
||||
private Integer removeSourceBranch = 0;
|
||||
private String description;
|
||||
|
||||
@@ -1,29 +1,16 @@
|
||||
package net.geedge.asw.module.app.service;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import net.geedge.asw.module.app.entity.ApplicationEntity;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface IApplicationService extends IService<ApplicationEntity>{
|
||||
public interface IApplicationService {
|
||||
|
||||
ApplicationEntity detail(String id, String workspaceId);
|
||||
|
||||
Page queryList(Map<String, Object> params);
|
||||
|
||||
ApplicationEntity saveApplication(ApplicationEntity entity);
|
||||
|
||||
ApplicationEntity updateApplication(ApplicationEntity entity);
|
||||
|
||||
ApplicationEntity updateBasic(ApplicationEntity entity);
|
||||
|
||||
void removeApplication(List<String> ids);
|
||||
List<ApplicationEntity> queryList(String workspaceId, String branchName, String... names);
|
||||
|
||||
byte[] exportAppByFormat(List<ApplicationEntity> appList, String format);
|
||||
|
||||
List<ApplicationEntity> importAppByFormat(String workspaceId, String format, List<JSONObject> dataList);
|
||||
List<ApplicationEntity> importAppByFormat(String workspaceId, String branchName, String format, List<JSONObject> dataList);
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package net.geedge.asw.module.app.service;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
|
||||
import org.eclipse.jgit.dircache.DirCache;
|
||||
import org.eclipse.jgit.dircache.DirCacheEntry;
|
||||
import org.eclipse.jgit.lib.FileMode;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
|
||||
@@ -32,8 +34,12 @@ public interface IGitService {
|
||||
|
||||
String getLatestCommitId(String workspaceId, String branch);
|
||||
|
||||
String getMergeBase(String workspaceId, String branchA, String branchB);
|
||||
|
||||
ObjectId insertBlobFileToDatabase(Repository repository, byte[] data) throws IOException;
|
||||
|
||||
DirCacheEntry buildDirCacheEntry(String path, FileMode mode, ObjectId objectId);
|
||||
|
||||
List<Map<Object, Object>> getDiffFileListInCommits(String workspaceId, String newCommitId, String oldCommitId);
|
||||
|
||||
String mergeBranch(String workspaceId, String sourceBranch, String targetBranch, String message, List<Map<String, String>> resolveConflictFileContent) throws RuntimeException;
|
||||
@@ -52,7 +58,7 @@ public interface IGitService {
|
||||
|
||||
Map<Object, Object> infoApplicationFileContent(String workspaceId, String branch, String applicationName, String commitId, String file);
|
||||
|
||||
List<Map<Object, Object>> listCommitAfterMergeBase(String workspaceId, String srcBranch, String tgtBranch);
|
||||
List<Map<Object, Object>> listCommitRange(String workspaceId, String newCommitId, String oldCommitId);
|
||||
|
||||
List<String> getConflictFilePathInBranches(String workspaceId, String srcBranch, String tgtBranch);
|
||||
|
||||
|
||||
@@ -12,4 +12,8 @@ public interface ITSGApplicationService {
|
||||
|
||||
List<ApplicationEntity> tsg2402ToAsw(String workspaceId, List<JSONObject> dataList);
|
||||
|
||||
Map<Object, Object> aswToTsg2410(List<ApplicationEntity> appList);
|
||||
|
||||
List<ApplicationEntity> tsg2410ToAsw(String workspaceId, List<JSONObject> dataList);
|
||||
|
||||
}
|
||||
@@ -30,41 +30,42 @@ public class ApplicationAttachmentServiceImpl extends ServiceImpl<ApplicationAtt
|
||||
|
||||
private static final Log log = Log.get();
|
||||
|
||||
@Autowired
|
||||
private IApplicationService applicationService;
|
||||
// @Autowired
|
||||
// private IApplicationService applicationService;
|
||||
|
||||
@Override
|
||||
public ApplicationAttachmentEntity saveAttachment(Resource fileResource, String applicationId) {
|
||||
|
||||
ApplicationEntity app = applicationService.getById(applicationId);
|
||||
ApplicationAttachmentEntity entity = new ApplicationAttachmentEntity();
|
||||
try {
|
||||
entity.setName(fileResource.getFilename());
|
||||
entity.setCreateTimestamp(System.currentTimeMillis());
|
||||
entity.setCreateUserId(StpUtil.getLoginIdAsString());
|
||||
entity.setApplicationId(applicationId);
|
||||
|
||||
// path
|
||||
File destination = T.FileUtil.file(T.WebPathUtil.getRootPath(), app.getId(), fileResource.getFilename());
|
||||
FileUtils.copyInputStreamToFile(fileResource.getInputStream(), destination);
|
||||
entity.setPath(destination.getPath());
|
||||
|
||||
// 根据文件 applicationId path 判断是否已上存在,存在则响应当前实体
|
||||
ApplicationAttachmentEntity attachment = this.getOne(new LambdaQueryWrapper<ApplicationAttachmentEntity>()
|
||||
.eq(ApplicationAttachmentEntity::getApplicationId, applicationId)
|
||||
.eq(ApplicationAttachmentEntity::getPath, destination.getPath()));
|
||||
if (T.ObjectUtil.isNotNull(attachment)) {
|
||||
return attachment;
|
||||
}
|
||||
|
||||
// save
|
||||
this.save(entity);
|
||||
|
||||
} catch (IOException e) {
|
||||
log.error(e, "[saveAttachment] [error] [applicationId: {}]", applicationId);
|
||||
throw new ASWException(RCode.ERROR);
|
||||
}
|
||||
return entity;
|
||||
// ApplicationEntity app = applicationService.getById(applicationId);
|
||||
// ApplicationAttachmentEntity entity = new ApplicationAttachmentEntity();
|
||||
// try {
|
||||
// entity.setName(fileResource.getFilename());
|
||||
// entity.setCreateTimestamp(System.currentTimeMillis());
|
||||
// entity.setCreateUserId(StpUtil.getLoginIdAsString());
|
||||
// entity.setApplicationId(applicationId);
|
||||
//
|
||||
// // path
|
||||
// File destination = T.FileUtil.file(T.WebPathUtil.getRootPath(), app.getId(), fileResource.getFilename());
|
||||
// FileUtils.copyInputStreamToFile(fileResource.getInputStream(), destination);
|
||||
// entity.setPath(destination.getPath());
|
||||
//
|
||||
// // 根据文件 applicationId path 判断是否已上存在,存在则响应当前实体
|
||||
// ApplicationAttachmentEntity attachment = this.getOne(new LambdaQueryWrapper<ApplicationAttachmentEntity>()
|
||||
// .eq(ApplicationAttachmentEntity::getApplicationId, applicationId)
|
||||
// .eq(ApplicationAttachmentEntity::getPath, destination.getPath()));
|
||||
// if (T.ObjectUtil.isNotNull(attachment)) {
|
||||
// return attachment;
|
||||
// }
|
||||
//
|
||||
// // save
|
||||
// this.save(entity);
|
||||
//
|
||||
// } catch (IOException e) {
|
||||
// log.error(e, "[saveAttachment] [error] [applicationId: {}]", applicationId);
|
||||
// throw new ASWException(RCode.ERROR);
|
||||
// }
|
||||
// return entity;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -39,15 +39,6 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
|
||||
ApplicationMergeEntity entity = this.getById(mrId);
|
||||
T.VerifyUtil.is(entity).notEmpty(RCode.SYS_RECORD_NOT_FOUND);
|
||||
|
||||
String commitId = entity.getCommitId();
|
||||
if (T.StrUtil.isNotEmpty(commitId)) {
|
||||
try {
|
||||
Map<Object, Object> infoCommit = gitService.infoCommit(entity.getWorkspaceId(), commitId);
|
||||
entity.setCommit(infoCommit);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
SysUserEntity user = userService.getById(entity.getCreateUserId());
|
||||
entity.setCreateUser(user);
|
||||
return entity;
|
||||
@@ -57,18 +48,6 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
|
||||
public Page queryList(Map<String, Object> params) {
|
||||
Page page = new Query(ApplicationMergeEntity.class).getPage(params);
|
||||
List<ApplicationMergeEntity> list = this.getBaseMapper().queryList(page, params);
|
||||
|
||||
for (ApplicationMergeEntity mergeEntity : list) {
|
||||
String commitId = mergeEntity.getCommitId();
|
||||
if (T.StrUtil.isNotEmpty(commitId)) {
|
||||
try {
|
||||
Map<Object, Object> infoCommit = gitService.infoCommit(mergeEntity.getWorkspaceId(), commitId);
|
||||
mergeEntity.setCommit(infoCommit);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
page.setRecords(list);
|
||||
return page;
|
||||
}
|
||||
@@ -81,6 +60,13 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
|
||||
// 默认状态
|
||||
entity.setStatus(MergeRequestStatus.OPEN.toString());
|
||||
|
||||
// start_commit_id
|
||||
String workspaceId = entity.getWorkspaceId();
|
||||
String sourceBranch = entity.getSourceBranch();
|
||||
String targetBranch = entity.getTargetBranch();
|
||||
String mergeBase = gitService.getMergeBase(workspaceId, sourceBranch, targetBranch);
|
||||
entity.setStartCommitId(mergeBase);
|
||||
|
||||
// save
|
||||
this.save(entity);
|
||||
|
||||
@@ -95,12 +81,24 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
|
||||
T.VerifyUtil.is(entity).notEmpty(RCode.SYS_RECORD_NOT_FOUND);
|
||||
|
||||
String workspaceId = entity.getWorkspaceId();
|
||||
String sourceBranch = entity.getSourceBranch();
|
||||
String targetBranch = entity.getTargetBranch();
|
||||
String oldCommitId = entity.getStartCommitId();
|
||||
String newCommitId = null;
|
||||
MergeRequestStatus mergeRequestStatus = MergeRequestStatus.getInstance(entity.getStatus());
|
||||
switch (mergeRequestStatus) {
|
||||
case OPEN: {
|
||||
newCommitId = gitService.getLatestCommitId(workspaceId, entity.getSourceBranch());
|
||||
break;
|
||||
}
|
||||
case CLOSED:
|
||||
case MERGED: {
|
||||
newCommitId = entity.getEndCommitId();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取 sourceBranch targetBranch 共同祖先之后, sourceBranch 的提交记录
|
||||
List<Map<Object, Object>> listCommitAfterMergeBase = gitService.listCommitAfterMergeBase(workspaceId, sourceBranch, targetBranch);
|
||||
return listCommitAfterMergeBase;
|
||||
// newCommitId-oldCommitId 期间的提交信息
|
||||
List<Map<Object, Object>> commitRange = gitService.listCommitRange(workspaceId, newCommitId, oldCommitId);
|
||||
return commitRange;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -113,14 +111,28 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
|
||||
String targetBranch = entity.getTargetBranch();
|
||||
|
||||
// 获取 sourceBranch,targetBranch 合并冲突文件
|
||||
List<String> conflictFileList = gitService.getConflictFilePathInBranches(workspaceId, sourceBranch, targetBranch);
|
||||
List<String> conflictFileList = T.ListUtil.list(true);
|
||||
|
||||
// src branch changed files
|
||||
String oldCommitId = entity.getStartCommitId();
|
||||
String newCommitId = null;
|
||||
MergeRequestStatus mergeRequestStatus = MergeRequestStatus.getInstance(entity.getStatus());
|
||||
switch (mergeRequestStatus) {
|
||||
case OPEN: {
|
||||
newCommitId = gitService.getLatestCommitId(workspaceId, sourceBranch);
|
||||
// open 状态下,获取 sourceBranch,targetBranch 冲突文件
|
||||
conflictFileList = gitService.getConflictFilePathInBranches(workspaceId, sourceBranch, targetBranch);
|
||||
break;
|
||||
}
|
||||
case CLOSED:
|
||||
case MERGED: {
|
||||
newCommitId = entity.getEndCommitId();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取 sourceBranch,targetBranch 文件差异
|
||||
String commitA = gitService.getLatestCommitId(workspaceId, sourceBranch);
|
||||
String commitB = gitService.getLatestCommitId(workspaceId, targetBranch);
|
||||
|
||||
List<Map<Object, Object>> diffFileListInCommits = gitService.getDiffFileListInCommits(workspaceId, commitA, commitB);
|
||||
List<Map<Object, Object>> diffFileListInCommits = gitService.getDiffFileListInCommits(workspaceId, newCommitId, oldCommitId);
|
||||
List<String> finalConflictFileList = conflictFileList;
|
||||
diffFileListInCommits.parallelStream()
|
||||
.forEach(m -> {
|
||||
T.MapUtil.renameKey(m, "oldContent", "sourceContent");
|
||||
@@ -132,19 +144,19 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
|
||||
String sourcePath = T.MapUtil.getStr(m, "sourcePath");
|
||||
String targetPath = T.MapUtil.getStr(m, "targetPath");
|
||||
m.put("conflict", false);
|
||||
if (conflictFileList.contains(sourcePath) || conflictFileList.contains(targetPath)) {
|
||||
if (finalConflictFileList.contains(sourcePath) || finalConflictFileList.contains(targetPath)) {
|
||||
m.put("conflict", true);
|
||||
}
|
||||
});
|
||||
|
||||
Map<Object, Object> sourceCommit = gitService.infoCommit(workspaceId, commitA);
|
||||
Map<Object, Object> targetCommit = gitService.infoCommit(workspaceId, commitB);
|
||||
Map<Object, Object> sourceCommit = gitService.infoCommit(workspaceId, oldCommitId);
|
||||
Map<Object, Object> targetCommit = gitService.infoCommit(workspaceId, newCommitId);
|
||||
|
||||
Map<Object, Object> m = T.MapUtil.builder()
|
||||
.put("sourceBranch", sourceBranch)
|
||||
.put("targetBranch", targetBranch)
|
||||
.put("sourceCommitId", commitA)
|
||||
.put("targetCommitId", commitB)
|
||||
.put("sourceCommitId", oldCommitId)
|
||||
.put("targetCommitId", newCommitId)
|
||||
.put("sourceCommit", sourceCommit)
|
||||
.put("targetCommit", targetCommit)
|
||||
.put("files", diffFileListInCommits)
|
||||
@@ -243,7 +255,7 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
|
||||
// merge
|
||||
try {
|
||||
String commitId = gitService.mergeBranch(workspaceId, srcBranch, tgtBranch, message, null);
|
||||
entity.setCommitId(commitId);
|
||||
entity.setEndCommitId(commitId);
|
||||
entity.setStatus(MergeRequestStatus.MERGED.toString());
|
||||
} catch (Exception e) {
|
||||
log.error(e, "[newMr] [merge error] [workspaceId: {}] [srcBranch: {}] [tgtBranch: {}] [msg: {}]", workspaceId, srcBranch, tgtBranch, e.getMessage());
|
||||
@@ -263,7 +275,7 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
|
||||
// update
|
||||
this.update(new LambdaUpdateWrapper<ApplicationMergeEntity>()
|
||||
.eq(ApplicationMergeEntity::getId, mrId)
|
||||
.set(ApplicationMergeEntity::getCommitId, entity.getCommitId())
|
||||
.set(ApplicationMergeEntity::getEndCommitId, entity.getEndCommitId())
|
||||
.set(ApplicationMergeEntity::getStatus, entity.getStatus())
|
||||
.set(ApplicationMergeEntity::getMessage, entity.getMessage())
|
||||
);
|
||||
@@ -273,9 +285,12 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
|
||||
String updateStatus = StrUtil.equals(MergeRequestStatus.OPEN.toString(), entity.getStatus()) ? MergeRequestStatus.CLOSED.toString() : entity.getStatus();
|
||||
entity.setStatus(updateStatus);
|
||||
|
||||
// 关闭请求,保留当前 src branch last commit = end_commit_id
|
||||
String latestCommitId = gitService.getLatestCommitId(entity.getWorkspaceId(), entity.getSourceBranch());
|
||||
this.update(new LambdaUpdateWrapper<ApplicationMergeEntity>()
|
||||
.eq(ApplicationMergeEntity::getId, mrId)
|
||||
.set(ApplicationMergeEntity::getStatus, updateStatus)
|
||||
.set(ApplicationMergeEntity::getEndCommitId, latestCommitId)
|
||||
);
|
||||
return entity;
|
||||
}
|
||||
|
||||
@@ -1,249 +1,220 @@
|
||||
package net.geedge.asw.module.app.service.impl;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.json.JSON;
|
||||
import cn.hutool.json.JSONConfig;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.log.Log;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import net.geedge.asw.common.config.Query;
|
||||
import net.geedge.asw.common.util.ASWException;
|
||||
import net.geedge.asw.common.util.RCode;
|
||||
import net.geedge.asw.common.util.T;
|
||||
import net.geedge.asw.module.app.dao.ApplicationDao;
|
||||
import net.geedge.asw.module.app.entity.*;
|
||||
import net.geedge.asw.module.app.service.*;
|
||||
import net.geedge.asw.module.sys.entity.SysUserEntity;
|
||||
import net.geedge.asw.module.sys.service.ISysUserService;
|
||||
import net.geedge.asw.module.app.entity.ApplicationEntity;
|
||||
import net.geedge.asw.module.app.service.IApplicationService;
|
||||
import net.geedge.asw.module.app.service.IGitService;
|
||||
import net.geedge.asw.module.app.service.ITSGApplicationService;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
|
||||
import org.eclipse.jgit.dircache.DirCache;
|
||||
import org.eclipse.jgit.dircache.DirCacheBuilder;
|
||||
import org.eclipse.jgit.dircache.DirCacheEntry;
|
||||
import org.eclipse.jgit.lib.FileMode;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.ObjectLoader;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.eclipse.jgit.revwalk.RevTree;
|
||||
import org.eclipse.jgit.revwalk.RevWalk;
|
||||
import org.eclipse.jgit.treewalk.TreeWalk;
|
||||
import org.eclipse.jgit.treewalk.filter.PathFilter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
|
||||
@Service
|
||||
public class ApplicationServiceImpl extends ServiceImpl<ApplicationDao, ApplicationEntity> implements IApplicationService {
|
||||
public class ApplicationServiceImpl implements IApplicationService {
|
||||
|
||||
private static final Log log = Log.get();
|
||||
|
||||
@Autowired
|
||||
private IApplicationLogService applicationLogService;
|
||||
|
||||
private IGitService gitService;
|
||||
|
||||
@Autowired
|
||||
private ISysUserService userService;
|
||||
|
||||
@Autowired
|
||||
private IApplicationSignatureService signatureService;
|
||||
|
||||
@Autowired
|
||||
private IApplicationNoteService noteService;
|
||||
|
||||
@Autowired
|
||||
private IApplicationHrefService hrefService;
|
||||
|
||||
@Autowired
|
||||
private IApplicationAttachmentService attachmentService;
|
||||
|
||||
@Autowired
|
||||
private ITSGApplicationService tsgApplicationService;
|
||||
@Qualifier("tsg2402ApplicationService")
|
||||
private ITSGApplicationService tsg2402ApplicationService;
|
||||
|
||||
@Override
|
||||
public ApplicationEntity detail(String id, String workspaceId) {
|
||||
ApplicationEntity app = this.getOne(new LambdaQueryWrapper<ApplicationEntity>()
|
||||
.eq(ApplicationEntity::getId, id)
|
||||
.eq(ApplicationEntity::getWorkspaceId, workspaceId));
|
||||
public List<ApplicationEntity> queryList(String workspaceId, String branch, String... names) {
|
||||
List<ApplicationEntity> resultList = T.ListUtil.list(true);
|
||||
|
||||
ApplicationSignatureEntity signature = signatureService.getOne(new LambdaQueryWrapper<ApplicationSignatureEntity>()
|
||||
.eq(ApplicationSignatureEntity::getApplicationId, app.getId())
|
||||
.orderByDesc(ApplicationSignatureEntity::getOpVersion)
|
||||
.last("limit 1"));
|
||||
app.setSignature(signature);
|
||||
try (Git git = gitService.getGitInstance(workspaceId)) {
|
||||
Repository repository = git.getRepository();
|
||||
|
||||
ApplicationNoteEntity note = noteService.getOne(new LambdaQueryWrapper<ApplicationNoteEntity>()
|
||||
.eq(ApplicationNoteEntity::getApplicationId, app.getId())
|
||||
.orderByDesc(ApplicationNoteEntity::getOpVersion)
|
||||
.last("limit 1"));
|
||||
app.setNote(note);
|
||||
try (TreeWalk treeWalk = new TreeWalk(repository);
|
||||
RevWalk revWalk = new RevWalk(repository)) {
|
||||
|
||||
List<ApplicationAttachmentEntity> attachmentEntityList = attachmentService.list(new LambdaQueryWrapper<ApplicationAttachmentEntity>()
|
||||
.eq(ApplicationAttachmentEntity::getApplicationId, app.getId()));
|
||||
attachmentEntityList.stream().forEach(x -> x.setPath(null));
|
||||
app.setAttatchments(attachmentEntityList);
|
||||
ObjectId branchRef = repository.resolve(branch);
|
||||
treeWalk.addTree(revWalk.parseTree(branchRef));
|
||||
treeWalk.setFilter(PathFilter.create("applications/"));
|
||||
treeWalk.setRecursive(true);
|
||||
|
||||
List<ApplicationHrefEntity> hrefEntityList = hrefService.list(new LambdaQueryWrapper<ApplicationHrefEntity>()
|
||||
.eq(ApplicationHrefEntity::getApplicationId, app.getId()));
|
||||
app.setHrefs(hrefEntityList);
|
||||
Map<String, String> signatureMapping = T.MapUtil.newHashMap();
|
||||
|
||||
SysUserEntity createUser = userService.getById(app.getCreateUserId());
|
||||
SysUserEntity updateUser = userService.getById(app.getUpdateUserId());
|
||||
app.setCreateUser(createUser);
|
||||
app.setUpdateUser(updateUser);
|
||||
|
||||
return app;
|
||||
while (treeWalk.next()) {
|
||||
String filePath = treeWalk.getPathString();
|
||||
String applicationName = T.PathUtil.getPathEle(Path.of(filePath), 1).toString();
|
||||
if (T.BooleanUtil.and(
|
||||
T.ObjectUtil.isNotEmpty(names),
|
||||
!Arrays.asList(names).contains(applicationName))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page queryList(Map<String, Object> params) {
|
||||
Page page = new Query(ApplicationEntity.class).getPage(params);
|
||||
List<ApplicationEntity> packageList = this.getBaseMapper().queryList(page, params);
|
||||
page.setRecords(packageList);
|
||||
return page;
|
||||
switch (treeWalk.getNameString()) {
|
||||
case "meta.json": {
|
||||
ObjectLoader loader = repository.open(treeWalk.getObjectId(0));
|
||||
String metaJsonStr = T.StrUtil.utf8Str(loader.getBytes());
|
||||
metaJsonStr = T.StrUtil.emptyToDefault(metaJsonStr, T.StrUtil.EMPTY_JSON);
|
||||
|
||||
ApplicationEntity application = T.JSONUtil.toBean(metaJsonStr, ApplicationEntity.class);
|
||||
application.setName(applicationName);
|
||||
resultList.add(application);
|
||||
break;
|
||||
}
|
||||
|
||||
private void validateParam(ApplicationEntity entity, boolean isUpdate) {
|
||||
ApplicationEntity one = this.getOne(new LambdaQueryWrapper<ApplicationEntity>()
|
||||
.eq(ApplicationEntity::getWorkspaceId, entity.getWorkspaceId())
|
||||
.eq(ApplicationEntity::getName, entity.getName()));
|
||||
|
||||
if (T.ObjectUtil.isNotNull(one) && !isUpdate || T.ObjectUtil.isNotNull(one) && isUpdate && !T.StrUtil.equals(entity.getId(), one.getId())) {
|
||||
throw ASWException.builder().rcode(RCode.APP_DUPLICATE_RECORD).build();
|
||||
case "signature.json": {
|
||||
ObjectLoader loader = repository.open(treeWalk.getObjectId(0));
|
||||
signatureMapping.put(applicationName, T.StrUtil.utf8Str(loader.getBytes()));
|
||||
break;
|
||||
}
|
||||
|
||||
// package name format
|
||||
if (T.ObjectUtil.isNotEmpty(entity.getPackageName()) && !T.JSONUtil.isTypeJSON(entity.getPackageName())) {
|
||||
throw ASWException.builder().rcode(RCode.APP_PACKAGE_NAME_FORMAT_ERROR).build();
|
||||
} else if (T.ObjectUtil.isEmpty(entity.getPackageName())) {
|
||||
entity.setPackageName("{}");
|
||||
}
|
||||
|
||||
// tags name format
|
||||
if (T.StrUtil.isNotEmpty(entity.getTags()) && !T.JSONUtil.isTypeJSON(entity.getTags())) {
|
||||
throw ASWException.builder().rcode(RCode.APP_TAGS_FORMAT_ERROR).build();
|
||||
}
|
||||
|
||||
// signature
|
||||
if (T.ObjectUtil.isNotEmpty(entity.getSignature())) {
|
||||
if (!T.StrUtil.isNotEmpty(entity.getSignature().getContent())){
|
||||
throw ASWException.builder().rcode(RCode.APP_SIGNATURE_CONTENT_CANNOT_EMPTY).build();
|
||||
}
|
||||
|
||||
if (!T.JSONUtil.isTypeJSON(entity.getSignature().getContent())){
|
||||
throw ASWException.builder().rcode(RCode.APP_SIGNATURE_CONTENT_CANNOT_EMPTY).build();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// note
|
||||
/* if (T.ObjectUtil.isNotEmpty(entity.getNote()) && !T.StrUtil.isNotEmpty(entity.getNote().getContent())) {
|
||||
throw ASWException.builder().rcode(RCode.APP_NOTE_CONTENT_CANNOT_EMPTY).build();
|
||||
}*/
|
||||
|
||||
// properties
|
||||
if (T.ObjectUtil.isNotEmpty(entity.getProperties()) && !T.JSONUtil.isTypeJSON(entity.getProperties().toString())) {
|
||||
throw ASWException.builder().rcode(RCode.APP_PROPERTIES_FORMAT_ERROR).build();
|
||||
for (ApplicationEntity entity : resultList) {
|
||||
String name = entity.getName();
|
||||
String signature = signatureMapping.getOrDefault(name, "");
|
||||
if (T.StrUtil.isNotEmpty(signature)) {
|
||||
JSONObject jsonObject = T.JSONUtil.parseObj(signature);
|
||||
entity.setSignature(jsonObject);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error(e, "[queryList] [error] [workspaceId: {}] [branch: {}]", workspaceId, branch);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
public void saveOrUpdateBatch(String workspaceId, String branch, String commitMessage, List<ApplicationEntity> list) {
|
||||
try (Git git = gitService.getGitInstance(workspaceId);
|
||||
Repository repository = git.getRepository();
|
||||
RevWalk revWalk = new RevWalk(repository)) {
|
||||
|
||||
ObjectId branchRef = repository.resolve(branch);
|
||||
RevTree revTree = revWalk.parseTree(branchRef);
|
||||
|
||||
// 先查询,区分 新增APP、修改APP
|
||||
List<ApplicationEntity> addAppList = T.ListUtil.list(true);
|
||||
List<ApplicationEntity> updateAppList = T.ListUtil.list(true);
|
||||
try (TreeWalk treeWalk = new TreeWalk(repository)) {
|
||||
treeWalk.addTree(revTree);
|
||||
treeWalk.setRecursive(true);
|
||||
treeWalk.setFilter(PathFilter.create("applications/"));
|
||||
HashSet<String> appNameListInDb = new HashSet<>();
|
||||
while (treeWalk.next()) {
|
||||
String appName = T.PathUtil.getPathEle(Path.of(treeWalk.getPathString()), 1).toString();
|
||||
appNameListInDb.add(appName);
|
||||
}
|
||||
list.parallelStream().forEach(entity -> {
|
||||
if (appNameListInDb.contains(entity.getName())) {
|
||||
updateAppList.add(entity);
|
||||
} else {
|
||||
addAppList.add(entity);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ApplicationEntity saveApplication(ApplicationEntity entity) {
|
||||
// 修改文件路径信息
|
||||
List<String> updateFilePath = T.ListUtil.list(true);
|
||||
updateAppList.parallelStream().forEach(entity -> {
|
||||
updateFilePath.add(T.StrUtil.concat(true, "applications/", entity.getName(), "/meta.json"));
|
||||
updateFilePath.add(T.StrUtil.concat(true, "applications/", entity.getName(), "/signature.json"));
|
||||
});
|
||||
|
||||
this.validateParam(entity, false);
|
||||
// build tree
|
||||
DirCache newTree = DirCache.newInCore();
|
||||
DirCacheBuilder newTreeBuilder = newTree.builder();
|
||||
try (TreeWalk treeWalk = new TreeWalk(repository)) {
|
||||
treeWalk.addTree(revTree);
|
||||
treeWalk.setRecursive(true);
|
||||
|
||||
while (treeWalk.next()) {
|
||||
// 先删
|
||||
String filePath = treeWalk.getPathString();
|
||||
if (!updateFilePath.contains(filePath)) {
|
||||
DirCacheEntry entry = new DirCacheEntry(filePath);
|
||||
entry.setFileMode(treeWalk.getFileMode(0));
|
||||
entry.setObjectId(treeWalk.getObjectId(0));
|
||||
newTreeBuilder.add(entry);
|
||||
}
|
||||
}
|
||||
// 新增APP
|
||||
for (ApplicationEntity entity : addAppList) {
|
||||
for (String fileName : T.ListUtil.of("README.md", "meta.json", "signature.json", "icon.png")) {
|
||||
String fileContent = T.StrUtil.EMPTY;
|
||||
if ("meta.json".equals(fileName)) {
|
||||
JSONObject tempJSONObject = T.JSONUtil.parseObj(entity);
|
||||
tempJSONObject.remove("signature");
|
||||
fileContent = T.JSONUtil.parse(tempJSONObject).toJSONString(2);
|
||||
}
|
||||
if ("signature.json".equals(fileName)) {
|
||||
String jsonStr = T.JSONUtil.toJsonStr(entity.getSignature());
|
||||
JSONObject tempJSONObject = T.JSONUtil.parseObj(jsonStr);
|
||||
fileContent = T.JSONUtil.parse(tempJSONObject).toJSONString(2);
|
||||
}
|
||||
// save
|
||||
entity.setCreateTimestamp(System.currentTimeMillis());
|
||||
entity.setUpdateTimestamp(System.currentTimeMillis());
|
||||
entity.setCreateUserId(StpUtil.getLoginIdAsString());
|
||||
entity.setUpdateUserId(StpUtil.getLoginIdAsString());
|
||||
this.save(entity);
|
||||
String filePath = T.StrUtil.concat(true, "applications/", entity.getName(), "/", fileName);
|
||||
DirCacheEntry dirCacheEntry = new DirCacheEntry(filePath);
|
||||
dirCacheEntry.setFileMode(FileMode.REGULAR_FILE);
|
||||
|
||||
if (T.ObjectUtil.isNotEmpty(entity.getSignature())){
|
||||
// save signature
|
||||
signatureService.saveSignature(entity.getSignature(), entity.getId());
|
||||
ObjectId blobId = gitService.insertBlobFileToDatabase(repository, fileContent.getBytes());
|
||||
dirCacheEntry.setObjectId(blobId);
|
||||
newTreeBuilder.add(dirCacheEntry);
|
||||
}
|
||||
|
||||
if (T.ObjectUtil.isNotEmpty(entity.getNote())){
|
||||
//save note
|
||||
noteService.saveNote(entity.getNote(), entity.getId());
|
||||
}
|
||||
// 修改APP
|
||||
for (ApplicationEntity entity : updateAppList) {
|
||||
// meta.json
|
||||
JSONObject jsonObject = T.JSONUtil.parseObj(entity);
|
||||
jsonObject.remove("signature");
|
||||
|
||||
String fileContent = T.JSONUtil.parse(jsonObject).toJSONString(2);
|
||||
ObjectId objectId = gitService.insertBlobFileToDatabase(repository, fileContent.getBytes());
|
||||
DirCacheEntry dirCacheEntry = gitService.buildDirCacheEntry(T.StrUtil.concat(true, "applications/", entity.getName(), "/meta.json"), FileMode.REGULAR_FILE, objectId);
|
||||
newTreeBuilder.add(dirCacheEntry);
|
||||
|
||||
return entity;
|
||||
// signature.json
|
||||
String jsonStr = T.JSONUtil.toJsonStr(entity.getSignature());
|
||||
JSONObject jsonObject2 = T.JSONUtil.parseObj(jsonStr);
|
||||
|
||||
String fileContent2 = T.JSONUtil.parse(jsonObject2).toJSONString(2);
|
||||
ObjectId objectId2 = gitService.insertBlobFileToDatabase(repository, fileContent2.getBytes());
|
||||
DirCacheEntry dirCacheEntry2 = gitService.buildDirCacheEntry(T.StrUtil.concat(true, "applications/", entity.getName(), "/signature.json"), FileMode.REGULAR_FILE, objectId2);
|
||||
newTreeBuilder.add(dirCacheEntry2);
|
||||
}
|
||||
newTreeBuilder.finish();
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ApplicationEntity updateApplication(ApplicationEntity entity) {
|
||||
|
||||
this.validateParam(entity, true);
|
||||
|
||||
ApplicationEntity one = this.getById(entity.getId());
|
||||
entity.setUpdateTimestamp(System.currentTimeMillis());
|
||||
entity.setUpdateUserId(StpUtil.getLoginIdAsString());
|
||||
entity.setOpVersion(one.getOpVersion() + 1);
|
||||
|
||||
// update
|
||||
this.updateById(entity);
|
||||
|
||||
// save log
|
||||
this.saveApplicationToLog(one);
|
||||
|
||||
if (T.ObjectUtil.isNotEmpty(entity.getSignature())){
|
||||
// save signature
|
||||
signatureService.saveSignature(entity.getSignature(), entity.getId());
|
||||
RevCommit commitId = revWalk.parseCommit(branchRef);
|
||||
boolean success = gitService.commitIndex(repository, branch, newTree, commitId, null, commitMessage);
|
||||
log.info("[saveOrUpdateBatch] [workspaceId: {}] [branch: {}] [commitId: {}] [success: {}]", workspaceId, branch, commitId, success);
|
||||
}
|
||||
|
||||
if (T.ObjectUtil.isNotEmpty(entity.getNote())){
|
||||
//save note
|
||||
noteService.saveNote(entity.getNote(), entity.getId());
|
||||
} catch (IOException | ConcurrentRefUpdateException e) {
|
||||
log.error(e, "[saveOrUpdateBatch] [error] [workspaceId: {}] [branch: {}]", workspaceId, branch);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
private void saveApplicationToLog(ApplicationEntity one) {
|
||||
ApplicationLogEntity applicationLogEntity = T.BeanUtil.toBean(one, ApplicationLogEntity.class);
|
||||
applicationLogEntity.setUpdateTimestamp(System.currentTimeMillis());
|
||||
applicationLogEntity.setUpdateUserId(StpUtil.getLoginIdAsString());
|
||||
applicationLogEntity.setCreateTimestamp(System.currentTimeMillis());
|
||||
applicationLogEntity.setCreateUserId(StpUtil.getLoginIdAsString());
|
||||
applicationLogService.save(applicationLogEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void removeApplication(List<String> ids) {
|
||||
// remove
|
||||
this.removeBatchByIds(ids);
|
||||
applicationLogService.removeBatchByIds(ids);
|
||||
signatureService.remove(new LambdaQueryWrapper<ApplicationSignatureEntity>().in(ApplicationSignatureEntity::getApplicationId, ids));
|
||||
noteService.remove(new LambdaQueryWrapper<ApplicationNoteEntity>().in(ApplicationNoteEntity::getApplicationId, ids));
|
||||
attachmentService.remove(new LambdaQueryWrapper<ApplicationAttachmentEntity>().in(ApplicationAttachmentEntity::getApplicationId, ids));
|
||||
hrefService.remove(new LambdaQueryWrapper<ApplicationHrefEntity>().in(ApplicationHrefEntity::getApplicationId, ids));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApplicationEntity updateBasic(ApplicationEntity entity) {
|
||||
|
||||
ApplicationEntity one = this.getById(entity.getId());
|
||||
if (T.ObjectUtil.isNotNull(one) && !T.StrUtil.equals(entity.getId(), one.getId())) {
|
||||
throw ASWException.builder().rcode(RCode.APP_DUPLICATE_RECORD).build();
|
||||
}
|
||||
|
||||
// package name format
|
||||
if (T.ObjectUtil.isNotEmpty(entity.getPackageName()) && !T.JSONUtil.isTypeJSON(entity.getPackageName())) {
|
||||
throw ASWException.builder().rcode(RCode.APP_PACKAGE_NAME_FORMAT_ERROR).build();
|
||||
} else if (T.ObjectUtil.isEmpty(entity.getPackageName())) {
|
||||
entity.setPackageName("{}");
|
||||
}
|
||||
|
||||
// properties
|
||||
if (T.ObjectUtil.isNotEmpty(entity.getProperties()) && !T.JSONUtil.isTypeJSON(entity.getProperties().toString())) {
|
||||
throw ASWException.builder().rcode(RCode.APP_PROPERTIES_FORMAT_ERROR).build();
|
||||
}
|
||||
|
||||
entity.setUpdateTimestamp(System.currentTimeMillis());
|
||||
entity.setUpdateUserId(StpUtil.getLoginIdAsString());
|
||||
entity.setOpVersion(one.getOpVersion() + 1);
|
||||
|
||||
this.saveApplicationToLog(one);
|
||||
this.updateById(entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -251,7 +222,7 @@ public class ApplicationServiceImpl extends ServiceImpl<ApplicationDao, Applicat
|
||||
try {
|
||||
switch (format) {
|
||||
case "tsg2402": {
|
||||
Map<Object, Object> m = tsgApplicationService.aswToTsg2402(appList);
|
||||
Map<Object, Object> m = tsg2402ApplicationService.aswToTsg2402(appList);
|
||||
JSON json = new JSONObject(m, JSONConfig.create().setIgnoreNullValue(false).setKeyComparator(String::compareToIgnoreCase));
|
||||
return T.StrUtil.bytes(json.toJSONString(0));
|
||||
}
|
||||
@@ -266,12 +237,15 @@ public class ApplicationServiceImpl extends ServiceImpl<ApplicationDao, Applicat
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public List<ApplicationEntity> importAppByFormat(String workspaceId, String format, List<JSONObject> dataList) {
|
||||
public List<ApplicationEntity> importAppByFormat(String workspaceId, String branchName, String format, List<JSONObject> dataList) {
|
||||
try {
|
||||
switch (format) {
|
||||
case "tsg2402": {
|
||||
List<ApplicationEntity> records = tsgApplicationService.tsg2402ToAsw(workspaceId, dataList);
|
||||
List<ApplicationEntity> records = tsg2402ApplicationService.tsg2402ToAsw(workspaceId, dataList);
|
||||
|
||||
// commit
|
||||
String commitMessage = "feat: import application data from TSG system (version 2402)";
|
||||
this.saveOrUpdateBatch(workspaceId, branchName, commitMessage, records);
|
||||
return records;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -27,7 +27,6 @@ import org.eclipse.jgit.merge.MergeStrategy;
|
||||
import org.eclipse.jgit.merge.RecursiveMerger;
|
||||
import org.eclipse.jgit.merge.ThreeWayMerger;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.eclipse.jgit.revwalk.RevSort;
|
||||
import org.eclipse.jgit.revwalk.RevWalk;
|
||||
import org.eclipse.jgit.revwalk.filter.RevFilter;
|
||||
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
|
||||
@@ -152,15 +151,11 @@ public class GitServiceImpl implements IGitService {
|
||||
Repository repository = git.getRepository();
|
||||
ObjectInserter inserter = repository.getObjectDatabase().newInserter();
|
||||
) {
|
||||
|
||||
ObjectId objectId = this.insertBlobFileToDatabase(repository, "".getBytes());
|
||||
|
||||
DirCacheEntry entry = new DirCacheEntry("README.md");
|
||||
entry.setFileMode(FileMode.REGULAR_FILE);
|
||||
entry.setObjectId(objectId);
|
||||
|
||||
DirCache dirCache = DirCache.newInCore();
|
||||
DirCacheBuilder builder = dirCache.builder();
|
||||
|
||||
ObjectId objectId = this.insertBlobFileToDatabase(repository, "".getBytes());
|
||||
DirCacheEntry entry = this.buildDirCacheEntry("README.md", FileMode.REGULAR_FILE, objectId);
|
||||
builder.add(entry);
|
||||
builder.finish();
|
||||
|
||||
@@ -338,6 +333,19 @@ public class GitServiceImpl implements IGitService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMergeBase(String workspaceId, String branchA, String branchB) {
|
||||
try (Git git = this.getGitInstance(workspaceId);
|
||||
Repository repository = git.getRepository();) {
|
||||
ObjectId branchAId = repository.resolve(branchA);
|
||||
ObjectId branchBId = repository.resolve(branchB);
|
||||
|
||||
return this.getMergeBase(repository, branchAId, branchBId);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 commitIdA -> commitIdB 文件差异
|
||||
*
|
||||
@@ -348,6 +356,7 @@ public class GitServiceImpl implements IGitService {
|
||||
*/
|
||||
@Override
|
||||
public List<Map<Object, Object>> getDiffFileListInCommits(String workspaceId, String commitIdA, String commitIdB) {
|
||||
log.info("[getDiffFileListInCommits] [begin] [workspaceId: {}] [commitIdA: {}] [commitIdB: {}]", workspaceId, commitIdA, commitIdB);
|
||||
try (Git git = this.getGitInstance(workspaceId);
|
||||
Repository repository = git.getRepository();
|
||||
RevWalk revWalk = new RevWalk(repository);
|
||||
@@ -570,15 +579,19 @@ public class GitServiceImpl implements IGitService {
|
||||
ObjectLoader loader = repository.open(treeWalk.getObjectId(0));
|
||||
String metaJsonStr = T.StrUtil.utf8Str(loader.getBytes());
|
||||
metaJsonStr = T.StrUtil.emptyToDefault(metaJsonStr, T.StrUtil.EMPTY_JSON);
|
||||
Map metaJsonMap = T.JSONUtil.toBean(metaJsonStr, Map.class);
|
||||
Map metaJsonMap = T.MapUtil.empty();
|
||||
try {
|
||||
metaJsonMap = T.JSONUtil.toBean(metaJsonStr, Map.class);
|
||||
} catch (Exception e) {
|
||||
log.error(e, "[listApplication] [meat.json format error] [applicationName: {}]", applicationName);
|
||||
}
|
||||
|
||||
Map<Object, Object> m = T.MapUtil.newHashMap(true);
|
||||
m.putAll(metaJsonMap);
|
||||
m.put("name", applicationName);
|
||||
|
||||
String appId = T.MapUtil.getStr(metaJsonMap, "id", "");
|
||||
String appDirPath = treeWalk.getPathString().replaceAll(fileName, "");
|
||||
appDirPathMapping.put(appId, appDirPath);
|
||||
appDirPathMapping.put(applicationName, appDirPath);
|
||||
|
||||
resultList.add(m);
|
||||
} else if (T.StrUtil.equals("icon.png", fileName)) {
|
||||
@@ -602,8 +615,7 @@ public class GitServiceImpl implements IGitService {
|
||||
}
|
||||
}
|
||||
|
||||
String appId = T.MapUtil.getStr(map, "id");
|
||||
RevCommit lastCommit = T.MapUtil.get(lastCommitMapping, appId, RevCommit.class);
|
||||
RevCommit lastCommit = T.MapUtil.get(lastCommitMapping, applicationName, RevCommit.class);
|
||||
map.put("commit", this.buildAswCommitInfo(lastCommit));
|
||||
}
|
||||
}
|
||||
@@ -711,9 +723,7 @@ public class GitServiceImpl implements IGitService {
|
||||
DirCache newTree = DirCache.newInCore();
|
||||
DirCacheBuilder newTreeBuilder = newTree.builder();
|
||||
while (treeWalk.next()) {
|
||||
DirCacheEntry entry = new DirCacheEntry(treeWalk.getPathString());
|
||||
entry.setFileMode(treeWalk.getFileMode(0));
|
||||
entry.setObjectId(treeWalk.getObjectId(0));
|
||||
DirCacheEntry entry = this.buildDirCacheEntry(treeWalk.getPathString(), treeWalk.getFileMode(0), treeWalk.getObjectId(0));
|
||||
newTreeBuilder.add(entry);
|
||||
}
|
||||
|
||||
@@ -723,9 +733,7 @@ public class GitServiceImpl implements IGitService {
|
||||
ObjectId blobId = entry.getValue();
|
||||
|
||||
// add file ref
|
||||
DirCacheEntry dirCacheEntry = new DirCacheEntry(filePath);
|
||||
dirCacheEntry.setFileMode(FileMode.REGULAR_FILE);
|
||||
dirCacheEntry.setObjectId(blobId);
|
||||
DirCacheEntry dirCacheEntry = this.buildDirCacheEntry(filePath, FileMode.REGULAR_FILE, blobId);
|
||||
newTreeBuilder.add(dirCacheEntry);
|
||||
}
|
||||
|
||||
@@ -761,9 +769,7 @@ public class GitServiceImpl implements IGitService {
|
||||
while (treeWalk.next()) {
|
||||
String pathString = treeWalk.getPathString();
|
||||
if (!pathString.startsWith(appFilePrefixStr)) {
|
||||
DirCacheEntry entry = new DirCacheEntry(pathString);
|
||||
entry.setFileMode(treeWalk.getFileMode(0));
|
||||
entry.setObjectId(treeWalk.getObjectId(0));
|
||||
DirCacheEntry entry = this.buildDirCacheEntry(pathString, treeWalk.getFileMode(0), treeWalk.getObjectId(0));
|
||||
newTreeBuilder.add(entry);
|
||||
}
|
||||
}
|
||||
@@ -838,9 +844,7 @@ public class GitServiceImpl implements IGitService {
|
||||
String pathString = treeWalk.getPathString();
|
||||
// 先删
|
||||
if (!updateFilePath.contains(pathString)) {
|
||||
DirCacheEntry entry = new DirCacheEntry(pathString);
|
||||
entry.setFileMode(treeWalk.getFileMode(0));
|
||||
entry.setObjectId(treeWalk.getObjectId(0));
|
||||
DirCacheEntry entry = this.buildDirCacheEntry(pathString, treeWalk.getFileMode(0), treeWalk.getObjectId(0));
|
||||
newTreeBuilder.add(entry);
|
||||
}
|
||||
}
|
||||
@@ -940,51 +944,45 @@ public class GitServiceImpl implements IGitService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 srcBranch tgtBranch 共同祖先之后, srcBranch 的提交记录
|
||||
* commit range
|
||||
* 沿着 parent(0) 的主路径提交列表,忽略所有分支路径的提交
|
||||
*
|
||||
* @param workspaceId
|
||||
* @param srcBranch
|
||||
* @param tgtBranch
|
||||
* @param newCommitId
|
||||
* @param oldCommitId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<Map<Object, Object>> listCommitAfterMergeBase(String workspaceId, String srcBranch, String tgtBranch) {
|
||||
log.info("[listCommitAfterMergeBase] [begin] [workspaceId: {}] [srcBranch: {}] [tgtBranch: {}]", workspaceId, srcBranch, tgtBranch);
|
||||
public List<Map<Object, Object>> listCommitRange(String workspaceId, String newCommitId, String oldCommitId) {
|
||||
log.info("[listCommitRange] [begin] [workspaceId: {}] [newCommitId: {}] [oldCommitId: {}]", workspaceId, newCommitId, oldCommitId);
|
||||
List<Map<Object, Object>> commitList = T.ListUtil.list(true);
|
||||
try (Git git = this.getGitInstance(workspaceId);
|
||||
Repository repository = git.getRepository();) {
|
||||
ObjectId branch1Id = repository.resolve(srcBranch);
|
||||
ObjectId branch2Id = repository.resolve(tgtBranch);
|
||||
|
||||
// Find the merge base
|
||||
String mergeBaseId = this.getMergeBase(repository, branch1Id, branch2Id);
|
||||
log.info("[listCommitAfterMergeBase] [mergeBase: {}]", mergeBaseId);
|
||||
if (T.StrUtil.isEmpty(mergeBaseId)) {
|
||||
return commitList;
|
||||
}
|
||||
|
||||
// Walk branch1's commits since the merge base
|
||||
try (RevWalk revWalk = new RevWalk(repository)) {
|
||||
revWalk.sort(RevSort.TOPO);
|
||||
RevCommit revCommit = revWalk.parseCommit(repository.resolve(newCommitId));
|
||||
|
||||
RevCommit mergeBase = revWalk.parseCommit(ObjectId.fromString(mergeBaseId));
|
||||
revWalk.markStart(revWalk.parseCommit(branch1Id));
|
||||
revWalk.markUninteresting(mergeBase);
|
||||
|
||||
for (RevCommit commit : revWalk) {
|
||||
commitList.add(this.buildAswCommitInfo(commit));
|
||||
|
||||
List<String> parentIds = Arrays.stream(commit.getParents()).map(RevCommit::getName).collect(Collectors.toList());
|
||||
if (parentIds.contains(mergeBaseId)) {
|
||||
Set<ObjectId> visitedCommits = new HashSet<>();
|
||||
while (revCommit != null && !visitedCommits.contains(revCommit.getId())) {
|
||||
if (oldCommitId != null && revCommit.getId().getName().equals(oldCommitId)) {
|
||||
break;
|
||||
}
|
||||
|
||||
commitList.add(this.buildAswCommitInfo(revCommit));
|
||||
visitedCommits.add(revCommit.getId());
|
||||
|
||||
// 沿着 parent(0) 前进
|
||||
if (revCommit.getParentCount() > 0) {
|
||||
revCommit = revWalk.parseCommit(revCommit.getParent(0));
|
||||
} else {
|
||||
revCommit = null;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error(e, "[listCommitAfterMergeBase] [error]");
|
||||
throw new RuntimeException(e.getMessage());
|
||||
log.error(e, "[listCommitRange] [error]");
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
log.info("[listCommitAfterMergeBase] [finshed] [workspaceId: {}] [commits size: {}]", workspaceId, commitList.size());
|
||||
log.info("[listCommitRange] [finshed] [workspaceId: {}] [commits size: {}]", workspaceId, commitList.size());
|
||||
}
|
||||
}
|
||||
return commitList;
|
||||
}
|
||||
@@ -1112,6 +1110,14 @@ public class GitServiceImpl implements IGitService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DirCacheEntry buildDirCacheEntry(String path, FileMode mode, ObjectId objectId) {
|
||||
DirCacheEntry dirCacheEntry = new DirCacheEntry(path);
|
||||
dirCacheEntry.setFileMode(mode);
|
||||
dirCacheEntry.setObjectId(objectId);
|
||||
return dirCacheEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 path,objectId 读取文件内容
|
||||
* 响应 Map,key=encoding,content
|
||||
@@ -1162,8 +1168,8 @@ public class GitServiceImpl implements IGitService {
|
||||
return mergeBase.getName();
|
||||
} catch (Exception e) {
|
||||
log.error(e, "Failed to determine merge base");
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,40 +1,31 @@
|
||||
package net.geedge.asw.module.app.service.impl;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.lang.Validator;
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.log.Log;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import net.geedge.asw.common.util.T;
|
||||
import net.geedge.asw.module.app.entity.ApplicationEntity;
|
||||
import net.geedge.asw.module.app.entity.ApplicationSignatureEntity;
|
||||
import net.geedge.asw.module.app.service.IApplicationService;
|
||||
import net.geedge.asw.module.app.service.IApplicationSignatureService;
|
||||
import net.geedge.asw.module.app.service.ITSGApplicationService;
|
||||
import net.geedge.asw.module.attribute.entity.AttributeEntity;
|
||||
import net.geedge.asw.module.attribute.service.IAttributeService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class TSGApplicationServiceImpl implements ITSGApplicationService {
|
||||
@Service("tsg2402ApplicationService")
|
||||
public class TSG2402ApplicationServiceImpl implements ITSGApplicationService {
|
||||
|
||||
private static final Log log = Log.get();
|
||||
|
||||
@Autowired
|
||||
private IAttributeService attributeService;
|
||||
|
||||
@Autowired
|
||||
private IApplicationService applicationService;
|
||||
|
||||
@Autowired
|
||||
private IApplicationSignatureService applicationSignatureService;
|
||||
|
||||
@Override
|
||||
public Map<Object, Object> aswToTsg2402(List<ApplicationEntity> appList) {
|
||||
|
||||
@@ -63,12 +54,11 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
|
||||
Map properties = (Map) app.getProperties();
|
||||
Map<Object, Object> app_properties = T.MapUtil.builder()
|
||||
.put("parent_app_id", 0)
|
||||
.put("parent_app_name", "null")
|
||||
.put("parent_app_name", T.MapUtil.getStr(properties, "parentApp", ""))
|
||||
.put("category", T.MapUtil.getStr(properties, "category", ""))
|
||||
.put("subcategory", T.MapUtil.getStr(properties, "subcategory", ""))
|
||||
.put("content", T.MapUtil.getStr(properties, "content", ""))
|
||||
.put("risk", T.MapUtil.getStr(properties, "risk", "1"))
|
||||
.put("characteristics", T.MapUtil.getStr(properties, "characteristics", ""))
|
||||
.put("deny_action", T.MapUtil.builder()
|
||||
.put("method", "drop")
|
||||
.put("after_n_packets", 0)
|
||||
@@ -85,8 +75,7 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
|
||||
application.put("app_properties", app_properties);
|
||||
|
||||
// app_surrogates
|
||||
ApplicationSignatureEntity signature = applicationSignatureService.queryLastVersionSignatureByAppId(app.getId());
|
||||
JSONObject jsonObject = T.JSONUtil.parseObj(signature.getContent());
|
||||
JSONObject jsonObject = (JSONObject) app.getSignature();
|
||||
JSONArray surrogates = jsonObject.getJSONArray("surrogates");
|
||||
if (!surrogates.isEmpty()) {
|
||||
List<Map> app_surrogates = T.ListUtil.list(true);
|
||||
@@ -124,8 +113,7 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
|
||||
|
||||
int sig_object_id = 10, signature_id = 0;
|
||||
for (ApplicationEntity app : appList) {
|
||||
ApplicationSignatureEntity signature = applicationSignatureService.queryLastVersionSignatureByAppId(app.getId());
|
||||
JSONObject jsonObject = T.JSONUtil.parseObj(signature.getContent());
|
||||
JSONObject jsonObject = (JSONObject) app.getSignature();
|
||||
JSONArray surrogates = jsonObject.getJSONArray("surrogates");
|
||||
List<Object> signaturesForApp = surrogates.stream()
|
||||
.map(obj -> ((JSONObject) obj).getJSONArray("signatures"))
|
||||
@@ -160,13 +148,20 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
|
||||
|
||||
List<Integer> source_object_ids = T.ListUtil.list(true);
|
||||
|
||||
// sig_objects
|
||||
JSONArray items = conditionJSONObj.getJSONArray("items");
|
||||
// objects
|
||||
JSONArray objects = conditionJSONObj.getJSONArray("objects");
|
||||
for (Object tempObject : objects) {
|
||||
JSONObject tempJsonObject = (JSONObject) tempObject;
|
||||
|
||||
String conditionType = attributeEntity.getObjectType();
|
||||
if ("application".equalsIgnoreCase(conditionType)) {
|
||||
// sig_objects
|
||||
JSONArray items = tempJsonObject.getJSONArray("items");
|
||||
String objectName = tempJsonObject.getStr("name");
|
||||
String objectType = tempJsonObject.getStr("type");
|
||||
String objectDescription = tempJsonObject.getStr("description");
|
||||
|
||||
if ("application".equalsIgnoreCase(objectType)) {
|
||||
continue;
|
||||
} else if ("boolean".equals(conditionType)) {
|
||||
} else if ("boolean".equals(objectType)) {
|
||||
items.stream()
|
||||
.map(obj -> (JSONObject) obj)
|
||||
.forEach(item -> {
|
||||
@@ -177,7 +172,7 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
|
||||
source_object_ids.add(3);
|
||||
}
|
||||
});
|
||||
} else if ("ip_protocol".equals(conditionType)) {
|
||||
} else if ("ip_protocol".equals(objectType)) {
|
||||
items.stream()
|
||||
.map(obj -> (JSONObject) obj)
|
||||
.forEach(item -> {
|
||||
@@ -191,26 +186,27 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
String name = T.MapUtil.getStr((JSONObject) items.getFirst(), "item");
|
||||
Map<Object, Object> sig_object = T.MapUtil.builder()
|
||||
.put("id", sig_object_id)
|
||||
.put("source_id", sig_object_id)
|
||||
.put("name", name)
|
||||
.put("source_name", name)
|
||||
.put("type", conditionType)
|
||||
.put("name", objectName)
|
||||
.put("source_name", objectName)
|
||||
.put("type", objectType)
|
||||
.put("sub_type", attributeEntity.getType())
|
||||
.put("member_type", "item")
|
||||
.put("uuid", T.IdUtil.fastSimpleUUID())
|
||||
.put("statistics_option", "none")
|
||||
.put("description", objectDescription)
|
||||
.build();
|
||||
|
||||
Map<Object, Object> member = this.buildTSG2402SignaturesMember(attributeEntity, items);
|
||||
Map<Object, Object> member = this.buildTSG2402SignaturesMember(objectType.toLowerCase(), items);
|
||||
sig_object.put("member", member);
|
||||
|
||||
sig_objects.add(sig_object);
|
||||
source_object_ids.add(sig_object_id);
|
||||
sig_object_id++;
|
||||
}
|
||||
}
|
||||
|
||||
or_condition_obj.put("source_object_ids", source_object_ids);
|
||||
Map<Object, Object> and_condition_item = T.MapUtil.builder()
|
||||
@@ -303,12 +299,11 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
|
||||
return m;
|
||||
}
|
||||
|
||||
private Map<Object, Object> buildTSG2402SignaturesMember(AttributeEntity attributeEntity, JSONArray itemArr) {
|
||||
private Map<Object, Object> buildTSG2402SignaturesMember(String objectType, JSONArray itemArr) {
|
||||
List<Object> list = T.ListUtil.list(true);
|
||||
itemArr.stream()
|
||||
.map(obj -> (JSONObject) obj)
|
||||
.forEach(item -> {
|
||||
String objectType = attributeEntity.getObjectType().toLowerCase();
|
||||
switch (objectType) {
|
||||
case "keywords":
|
||||
case "http_signature": {
|
||||
@@ -484,7 +479,6 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public List<ApplicationEntity> tsg2402ToAsw(String workspaceId, List<JSONObject> dataList) {
|
||||
List<ApplicationEntity> records = T.ListUtil.list(true);
|
||||
for (JSONObject tsgAppSourceData : dataList) {
|
||||
@@ -497,46 +491,42 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
|
||||
.map(obj -> (JSONObject) obj)
|
||||
.forEach(application -> {
|
||||
// application
|
||||
String app_id = application.getStr("app_id");
|
||||
String app_name = application.getStr("app_name");
|
||||
String app_longname = application.getStr("app_longname");
|
||||
String description = application.getStr("description");
|
||||
|
||||
JSONObject appProperties = application.getJSONObject("app_properties");
|
||||
String category = T.MapUtil.getStr(appProperties, "category", "");
|
||||
String subcategory = T.MapUtil.getStr(appProperties, "subcategory", "");
|
||||
String content = T.MapUtil.getStr(appProperties, "content", "");
|
||||
String parent_app_name = T.MapUtil.getStr(appProperties, "parent_app_name", "");
|
||||
int risk = T.MapUtil.getInt(appProperties, "risk", 1);
|
||||
String characteristics = T.MapUtil.getStr(appProperties, "characteristics", "");
|
||||
|
||||
Map<Object, Object> properties = T.MapUtil.builder()
|
||||
.put("category", category)
|
||||
.put("subcategory", subcategory)
|
||||
.put("content", content)
|
||||
.put("parentApp", parent_app_name)
|
||||
.put("risk", risk)
|
||||
.put("characteristics", characteristics)
|
||||
.build();
|
||||
|
||||
// save or update application
|
||||
// meta.json
|
||||
ApplicationEntity entity = new ApplicationEntity();
|
||||
entity.setId(app_id);
|
||||
entity.setName(app_name);
|
||||
entity.setLongName(app_longname);
|
||||
entity.setDescription(description);
|
||||
entity.setProperties(properties);
|
||||
entity.setPackageName("{}");
|
||||
entity.setWorkspaceId(workspaceId);
|
||||
entity.setCreateTimestamp(System.currentTimeMillis());
|
||||
entity.setUpdateTimestamp(System.currentTimeMillis());
|
||||
entity.setCreateUserId(StpUtil.getLoginIdAsString());
|
||||
entity.setUpdateUserId(StpUtil.getLoginIdAsString());
|
||||
|
||||
ApplicationEntity one = applicationService.getOne(new LambdaQueryWrapper<ApplicationEntity>()
|
||||
.eq(ApplicationEntity::getWorkspaceId, workspaceId)
|
||||
.eq(ApplicationEntity::getName, app_name));
|
||||
if (null != one) {
|
||||
entity.setId(one.getId());
|
||||
}
|
||||
applicationService.saveOrUpdate(entity);
|
||||
|
||||
records.add(entity);
|
||||
String applicationId = entity.getId();
|
||||
// default value
|
||||
entity.setDeveloper("");
|
||||
entity.setWebsite("");
|
||||
entity.setPackageName(
|
||||
T.MapUtil.builder()
|
||||
.put("android", "")
|
||||
.put("ios", "")
|
||||
.build()
|
||||
);
|
||||
|
||||
// surrogate - signature
|
||||
Map<String, List<String>> surrAndSignListMap = T.MapUtil.newHashMap();
|
||||
@@ -549,7 +539,6 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
List<Object> insertSurrogateList = T.ListUtil.list(true);
|
||||
for (Map.Entry<String, List<String>> entry : surrAndSignListMap.entrySet()) {
|
||||
String surrogateName = entry.getKey();
|
||||
@@ -575,19 +564,11 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
|
||||
.put("surrogates", insertSurrogateList)
|
||||
.build();
|
||||
|
||||
// save application signatrue
|
||||
ApplicationSignatureEntity signatureEntity = new ApplicationSignatureEntity();
|
||||
signatureEntity.setApplicationId(applicationId);
|
||||
signatureEntity.setContent(T.JSONUtil.toJsonStr(sm));
|
||||
signatureEntity.setCreateTimestamp(System.currentTimeMillis());
|
||||
signatureEntity.setCreateUserId(StpUtil.getLoginIdAsString());
|
||||
signatureEntity.setOpVersion(0L);
|
||||
// signature.json
|
||||
entity.setSignature(T.JSONUtil.parseObj(sm));
|
||||
|
||||
ApplicationSignatureEntity signatureLast = applicationSignatureService.queryLastVersionSignatureByAppId(applicationId);
|
||||
if (T.ObjectUtil.isNotEmpty(signatureLast)) {
|
||||
signatureEntity.setOpVersion(signatureLast.getOpVersion() + 1);
|
||||
}
|
||||
applicationSignatureService.save(signatureEntity);
|
||||
// add records
|
||||
records.add(entity);
|
||||
});
|
||||
}
|
||||
return records;
|
||||
@@ -642,20 +623,10 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<Map<Object, Object>> itemList = this.buildAswConditionItemsFromTSG2402(sourceObjectList);
|
||||
if (T.CollUtil.isEmpty(itemList)) continue;
|
||||
List<Map<Object, Object>> objects = this.buildAswConditionObjectsFromTSG2402(sourceObjectList);
|
||||
if (T.CollUtil.isEmpty(objects)) continue;
|
||||
|
||||
// 按 item value 去重
|
||||
List<Map<String, String>> distinctItemList = itemList.stream()
|
||||
.collect(Collectors.collectingAndThen(
|
||||
Collectors.toMap(
|
||||
map -> map.get("item"),
|
||||
map -> map,
|
||||
(existing, replacement) -> existing // 保留第一个出现的元素
|
||||
),
|
||||
map -> new ArrayList(map.values())
|
||||
));
|
||||
m.put("items", distinctItemList);
|
||||
m.put("objects", objects);
|
||||
conditionMapList.add(m);
|
||||
}
|
||||
|
||||
@@ -667,14 +638,17 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
|
||||
return surrogate;
|
||||
}
|
||||
|
||||
private List<Map<Object, Object>> buildAswConditionItemsFromTSG2402(List<JSONObject> sourceObjectList) {
|
||||
List<Map<Object, Object>> iiemList = T.ListUtil.list(true);
|
||||
private List<Map<Object, Object>> buildAswConditionObjectsFromTSG2402(List<JSONObject> sourceObjectList) {
|
||||
List<Map<Object, Object>> objectList = T.ListUtil.list(true);
|
||||
for (JSONObject jsonObject : sourceObjectList) {
|
||||
|
||||
String name = jsonObject.getStr("name");
|
||||
String type = jsonObject.getStr("type");
|
||||
String description = jsonObject.getStr("description");
|
||||
|
||||
JSONArray itemArr = (JSONArray) T.JSONUtil.getByPath(jsonObject, "member.items");
|
||||
itemArr = T.CollUtil.defaultIfEmpty(itemArr, new JSONArray());
|
||||
|
||||
List<Map<Object, Object>> items = T.ListUtil.list(true);
|
||||
switch (type) {
|
||||
case "http_signature":
|
||||
case "keywords": {
|
||||
@@ -727,7 +701,7 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
|
||||
if (T.StrUtil.isNotEmpty(context_name)) {
|
||||
m.put("district", context_name);
|
||||
}
|
||||
iiemList.add(m);
|
||||
items.add(m);
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -737,7 +711,7 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
|
||||
.map(obj -> (JSONObject) obj)
|
||||
.forEach(item -> {
|
||||
String str = (String) T.JSONUtil.getByPath(item, "string.patterns[0].keywords");
|
||||
iiemList.add(
|
||||
items.add(
|
||||
T.MapUtil.builder()
|
||||
.put("item", str)
|
||||
.put("description", "")
|
||||
@@ -761,7 +735,7 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
|
||||
if (!"0-65535" .equalsIgnoreCase(port)) {
|
||||
ipAddress = T.StrUtil.concat(true, ipAddress, "#", port);
|
||||
}
|
||||
iiemList.add(
|
||||
items.add(
|
||||
T.MapUtil.builder()
|
||||
.put("item", ipAddress)
|
||||
.put("description", "")
|
||||
@@ -778,7 +752,7 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
|
||||
if (T.StrUtil.isEmpty(port)) {
|
||||
port = (String) T.JSONUtil.getByPath(item, "port.port_range");
|
||||
}
|
||||
iiemList.add(
|
||||
items.add(
|
||||
T.MapUtil.builder()
|
||||
.put("item", port)
|
||||
.put("description", "")
|
||||
@@ -797,7 +771,7 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
|
||||
.put("item", low_boundary + "-" + up_boundary)
|
||||
.put("description", "")
|
||||
.build();
|
||||
iiemList.add(m);
|
||||
items.add(m);
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -807,7 +781,7 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
|
||||
.put("item", jsonObject.getStr("name"))
|
||||
.put("description", "")
|
||||
.build();
|
||||
iiemList.add(m);
|
||||
items.add(m);
|
||||
break;
|
||||
}
|
||||
case "application": {
|
||||
@@ -816,8 +790,28 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Map<Object, Object> m = T.MapUtil.builder()
|
||||
.put("name", name)
|
||||
.put("type", type)
|
||||
.put("description", description)
|
||||
.put("items", items)
|
||||
.build();
|
||||
objectList.add(m);
|
||||
}
|
||||
return iiemList;
|
||||
return objectList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Object, Object> aswToTsg2410(List<ApplicationEntity> appList) {
|
||||
// 不在这个类处理,在 TSG2410ApplicationServiceImpl 实现
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ApplicationEntity> tsg2410ToAsw(String workspaceId, List<JSONObject> dataList) {
|
||||
// 不在这个类处理,在 TSG2410ApplicationServiceImpl 实现
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,7 +7,8 @@
|
||||
<id column="id" property="id"/>
|
||||
<result column="source_branch" property="sourceBranch"/>
|
||||
<result column="target_branch" property="targetBranch"/>
|
||||
<result column="commit_id" property="commitId"/>
|
||||
<result column="start_commit_id" property="startCommitId"/>
|
||||
<result column="end_commit_id" property="endCommitId"/>
|
||||
<result column="title" property="title"/>
|
||||
<result column="remove_source_branch" property="removeSourceBranch"/>
|
||||
<result column="description" property="description"/>
|
||||
|
||||
@@ -361,7 +361,8 @@ CREATE TABLE `application_merge` (
|
||||
`id` VARCHAR(64) NOT NULL COMMENT '主键',
|
||||
`source_branch` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '源分支',
|
||||
`target_branch` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '目标分支',
|
||||
`commit_id` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '提交ID',
|
||||
`start_commit_id` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '起始提交ID,即source和target分支的共同parent id',
|
||||
`end_commit_id` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '终止提交ID,记录合并后的commit id',
|
||||
`title` VARCHAR(4096) NOT NULL DEFAULT '' COMMENT '标题',
|
||||
`remove_source_branch` int(1) NOT NULL DEFAULT 0 COMMENT '是否删除源分支, 1:删除;0:不删除 默认:0',
|
||||
`description` text NOT NULL DEFAULT '' COMMENT '描述信息',
|
||||
|
||||
Reference in New Issue
Block a user