feat: ASW-149 signature.json 格式更新,支持保存 object 名称类型

1. application 导入导出 数据源切换为 git
This commit is contained in:
shizhendong
2024-11-14 14:05:14 +08:00
parent fe55a7fcf8
commit 892a961fe1
9 changed files with 398 additions and 471 deletions

View File

@@ -2,24 +2,21 @@ package net.geedge.asw.module.app.controller;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import cn.hutool.log.Log; 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 jakarta.servlet.http.HttpServletResponse;
import net.geedge.asw.common.util.ASWException; import net.geedge.asw.common.util.ASWException;
import net.geedge.asw.common.util.R; import net.geedge.asw.common.util.R;
import net.geedge.asw.common.util.RCode; import net.geedge.asw.common.util.RCode;
import net.geedge.asw.common.util.T; import net.geedge.asw.common.util.T;
import net.geedge.asw.module.app.entity.*; import net.geedge.asw.module.app.entity.ApplicationEntity;
import net.geedge.asw.module.app.service.*; import net.geedge.asw.module.app.service.IApplicationService;
import net.geedge.asw.module.workspace.entity.WorkspaceEntity; import net.geedge.asw.module.workspace.entity.WorkspaceEntity;
import net.geedge.asw.module.workspace.service.IWorkspaceService; import net.geedge.asw.module.workspace.service.IWorkspaceService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -36,7 +33,7 @@ public class ApplicationController {
@Autowired @Autowired
private IApplicationService applicationService; private IApplicationService applicationService;
@Autowired /*@Autowired
private IApplicationSignatureService signatureService; private IApplicationSignatureService signatureService;
@Autowired @Autowired
@@ -267,11 +264,11 @@ public class ApplicationController {
.eq(ApplicationHrefEntity::getApplicationId, applicationId) .eq(ApplicationHrefEntity::getApplicationId, applicationId)
.in(ApplicationHrefEntity::getId, T.ListUtil.of(ids))); .in(ApplicationHrefEntity::getId, T.ListUtil.of(ids)));
return R.ok(); return R.ok();
} }*/
@PostMapping("/import") @PostMapping("/import")
public R importApplication(@RequestParam String workspaceId, public synchronized R importApplication(@RequestParam String workspaceId,
@RequestParam String branchName,
@RequestParam(defaultValue = "tsg2402") String format, @RequestParam(defaultValue = "tsg2402") String format,
@RequestParam(value = "files") List<MultipartFile> fileList) { @RequestParam(value = "files") List<MultipartFile> fileList) {
// validate // validate
@@ -292,25 +289,36 @@ public class ApplicationController {
throw new ASWException(RCode.APP_IMPORT_FILE_FORMAT_ERROR); 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 // 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() List<Map<String, String>> records = entityList.stream()
.map(entity -> Map.of("id", entity.getId())) .map(entity -> Map.of("name", entity.getName()))
.collect(Collectors.toList()); .collect(Collectors.toList());
return R.ok().putData("records", records); return R.ok().putData("records", records);
} }
@GetMapping("/export") @GetMapping("/export")
public void exportApplication(@RequestParam String workspaceId, public void exportApplication(@RequestParam String workspaceId,
@RequestParam String ids, @RequestParam String branchName,
@RequestParam String names,
@RequestParam(defaultValue = "tsg2402") String format, @RequestParam(defaultValue = "tsg2402") String format,
HttpServletResponse response) throws IOException { HttpServletResponse response) throws IOException {
// validate // validate
List<ApplicationEntity> appList = applicationService.list( List<ApplicationEntity> appList = applicationService.queryList(workspaceId, branchName, T.StrUtil.splitToArray(names, ","));
new LambdaQueryWrapper<ApplicationEntity>()
.eq(ApplicationEntity::getWorkspaceId, workspaceId)
.in(ApplicationEntity::getId, T.ListUtil.of(ids.split(",")))
);
T.VerifyUtil.is(appList).notEmpty(RCode.APP_NOT_EXIST); T.VerifyUtil.is(appList).notEmpty(RCode.APP_NOT_EXIST);
// format // format

View File

@@ -1,67 +1,26 @@
package net.geedge.asw.module.app.entity; package net.geedge.asw.module.app.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField; 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 com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.Data; import lombok.Data;
import net.geedge.asw.module.sys.entity.SysUserEntity;
import java.util.List;
@Data @Data
@TableName(value = "application", autoResultMap = true)
public class ApplicationEntity { public class ApplicationEntity {
@TableId(type = IdType.ASSIGN_UUID)
private String id; private String id;
private String name; private String name;
private String longName;
private String tags; private String developer;
private String packageName;
private String website; private String website;
private String description;
private String provider; @TableField(typeHandler = JacksonTypeHandler.class)
private Object packageName;
@TableField(typeHandler = JacksonTypeHandler.class) @TableField(typeHandler = JacksonTypeHandler.class)
private Object properties; private Object properties;
private String status; @TableField(typeHandler = JacksonTypeHandler.class)
private Object signature;
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;
} }

View File

@@ -1,29 +1,16 @@
package net.geedge.asw.module.app.service; package net.geedge.asw.module.app.service;
import cn.hutool.json.JSONObject; 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 net.geedge.asw.module.app.entity.ApplicationEntity;
import java.util.List; import java.util.List;
import java.util.Map;
public interface IApplicationService extends IService<ApplicationEntity>{ public interface IApplicationService {
ApplicationEntity detail(String id, String workspaceId); List<ApplicationEntity> queryList(String workspaceId, String branchName, String... names);
Page queryList(Map<String, Object> params);
ApplicationEntity saveApplication(ApplicationEntity entity);
ApplicationEntity updateApplication(ApplicationEntity entity);
ApplicationEntity updateBasic(ApplicationEntity entity);
void removeApplication(List<String> ids);
byte[] exportAppByFormat(List<ApplicationEntity> appList, String format); 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);
} }

View File

@@ -3,6 +3,8 @@ package net.geedge.asw.module.app.service;
import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException; import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
import org.eclipse.jgit.dircache.DirCache; 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.ObjectId;
import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Repository;
@@ -36,6 +38,8 @@ public interface IGitService {
ObjectId insertBlobFileToDatabase(Repository repository, byte[] data) throws IOException; 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); 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; String mergeBranch(String workspaceId, String sourceBranch, String targetBranch, String message, List<Map<String, String>> resolveConflictFileContent) throws RuntimeException;

View File

@@ -12,4 +12,8 @@ public interface ITSGApplicationService {
List<ApplicationEntity> tsg2402ToAsw(String workspaceId, List<JSONObject> dataList); List<ApplicationEntity> tsg2402ToAsw(String workspaceId, List<JSONObject> dataList);
Map<Object, Object> aswToTsg2410(List<ApplicationEntity> appList);
List<ApplicationEntity> tsg2410ToAsw(String workspaceId, List<JSONObject> dataList);
} }

View File

@@ -30,41 +30,42 @@ public class ApplicationAttachmentServiceImpl extends ServiceImpl<ApplicationAtt
private static final Log log = Log.get(); private static final Log log = Log.get();
@Autowired // @Autowired
private IApplicationService applicationService; // private IApplicationService applicationService;
@Override @Override
public ApplicationAttachmentEntity saveAttachment(Resource fileResource, String applicationId) { public ApplicationAttachmentEntity saveAttachment(Resource fileResource, String applicationId) {
ApplicationEntity app = applicationService.getById(applicationId); // ApplicationEntity app = applicationService.getById(applicationId);
ApplicationAttachmentEntity entity = new ApplicationAttachmentEntity(); // ApplicationAttachmentEntity entity = new ApplicationAttachmentEntity();
try { // try {
entity.setName(fileResource.getFilename()); // entity.setName(fileResource.getFilename());
entity.setCreateTimestamp(System.currentTimeMillis()); // entity.setCreateTimestamp(System.currentTimeMillis());
entity.setCreateUserId(StpUtil.getLoginIdAsString()); // entity.setCreateUserId(StpUtil.getLoginIdAsString());
entity.setApplicationId(applicationId); // entity.setApplicationId(applicationId);
//
// path // // path
File destination = T.FileUtil.file(T.WebPathUtil.getRootPath(), app.getId(), fileResource.getFilename()); // File destination = T.FileUtil.file(T.WebPathUtil.getRootPath(), app.getId(), fileResource.getFilename());
FileUtils.copyInputStreamToFile(fileResource.getInputStream(), destination); // FileUtils.copyInputStreamToFile(fileResource.getInputStream(), destination);
entity.setPath(destination.getPath()); // entity.setPath(destination.getPath());
//
// 根据文件 applicationId path 判断是否已上存在,存在则响应当前实体 // // 根据文件 applicationId path 判断是否已上存在,存在则响应当前实体
ApplicationAttachmentEntity attachment = this.getOne(new LambdaQueryWrapper<ApplicationAttachmentEntity>() // ApplicationAttachmentEntity attachment = this.getOne(new LambdaQueryWrapper<ApplicationAttachmentEntity>()
.eq(ApplicationAttachmentEntity::getApplicationId, applicationId) // .eq(ApplicationAttachmentEntity::getApplicationId, applicationId)
.eq(ApplicationAttachmentEntity::getPath, destination.getPath())); // .eq(ApplicationAttachmentEntity::getPath, destination.getPath()));
if (T.ObjectUtil.isNotNull(attachment)) { // if (T.ObjectUtil.isNotNull(attachment)) {
return attachment; // return attachment;
} // }
//
// save // // save
this.save(entity); // this.save(entity);
//
} catch (IOException e) { // } catch (IOException e) {
log.error(e, "[saveAttachment] [error] [applicationId: {}]", applicationId); // log.error(e, "[saveAttachment] [error] [applicationId: {}]", applicationId);
throw new ASWException(RCode.ERROR); // throw new ASWException(RCode.ERROR);
} // }
return entity; // return entity;
return null;
} }
@Override @Override

View File

@@ -1,249 +1,220 @@
package net.geedge.asw.module.app.service.impl; package net.geedge.asw.module.app.service.impl;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.json.JSON; import cn.hutool.json.JSON;
import cn.hutool.json.JSONConfig; import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import cn.hutool.log.Log; 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.ASWException;
import net.geedge.asw.common.util.RCode; import net.geedge.asw.common.util.RCode;
import net.geedge.asw.common.util.T; import net.geedge.asw.common.util.T;
import net.geedge.asw.module.app.dao.ApplicationDao; import net.geedge.asw.module.app.entity.ApplicationEntity;
import net.geedge.asw.module.app.entity.*; import net.geedge.asw.module.app.service.IApplicationService;
import net.geedge.asw.module.app.service.*; import net.geedge.asw.module.app.service.IGitService;
import net.geedge.asw.module.sys.entity.SysUserEntity; import net.geedge.asw.module.app.service.ITSGApplicationService;
import net.geedge.asw.module.sys.service.ISysUserService; 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.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList; import java.io.IOException;
import java.util.List; import java.nio.file.Path;
import java.util.Map; import java.util.*;
@Service @Service
public class ApplicationServiceImpl extends ServiceImpl<ApplicationDao, ApplicationEntity> implements IApplicationService { public class ApplicationServiceImpl implements IApplicationService {
private static final Log log = Log.get(); private static final Log log = Log.get();
@Autowired @Autowired
private IApplicationLogService applicationLogService; private IGitService gitService;
@Autowired @Autowired
private ISysUserService userService; @Qualifier("tsg2402ApplicationService")
private ITSGApplicationService tsg2402ApplicationService;
@Autowired
private IApplicationSignatureService signatureService;
@Autowired
private IApplicationNoteService noteService;
@Autowired
private IApplicationHrefService hrefService;
@Autowired
private IApplicationAttachmentService attachmentService;
@Autowired
private ITSGApplicationService tsgApplicationService;
@Override @Override
public ApplicationEntity detail(String id, String workspaceId) { public List<ApplicationEntity> queryList(String workspaceId, String branch, String... names) {
ApplicationEntity app = this.getOne(new LambdaQueryWrapper<ApplicationEntity>() List<ApplicationEntity> resultList = T.ListUtil.list(true);
.eq(ApplicationEntity::getId, id)
.eq(ApplicationEntity::getWorkspaceId, workspaceId));
ApplicationSignatureEntity signature = signatureService.getOne(new LambdaQueryWrapper<ApplicationSignatureEntity>() try (Git git = gitService.getGitInstance(workspaceId)) {
.eq(ApplicationSignatureEntity::getApplicationId, app.getId()) Repository repository = git.getRepository();
.orderByDesc(ApplicationSignatureEntity::getOpVersion)
.last("limit 1"));
app.setSignature(signature);
ApplicationNoteEntity note = noteService.getOne(new LambdaQueryWrapper<ApplicationNoteEntity>() try (TreeWalk treeWalk = new TreeWalk(repository);
.eq(ApplicationNoteEntity::getApplicationId, app.getId()) RevWalk revWalk = new RevWalk(repository)) {
.orderByDesc(ApplicationNoteEntity::getOpVersion)
.last("limit 1"));
app.setNote(note);
List<ApplicationAttachmentEntity> attachmentEntityList = attachmentService.list(new LambdaQueryWrapper<ApplicationAttachmentEntity>() ObjectId branchRef = repository.resolve(branch);
.eq(ApplicationAttachmentEntity::getApplicationId, app.getId())); treeWalk.addTree(revWalk.parseTree(branchRef));
attachmentEntityList.stream().forEach(x -> x.setPath(null)); treeWalk.setFilter(PathFilter.create("applications/"));
app.setAttatchments(attachmentEntityList); treeWalk.setRecursive(true);
List<ApplicationHrefEntity> hrefEntityList = hrefService.list(new LambdaQueryWrapper<ApplicationHrefEntity>() Map<String, String> signatureMapping = T.MapUtil.newHashMap();
.eq(ApplicationHrefEntity::getApplicationId, app.getId()));
app.setHrefs(hrefEntityList);
SysUserEntity createUser = userService.getById(app.getCreateUserId()); while (treeWalk.next()) {
SysUserEntity updateUser = userService.getById(app.getUpdateUserId()); String filePath = treeWalk.getPathString();
app.setCreateUser(createUser); String applicationName = T.PathUtil.getPathEle(Path.of(filePath), 1).toString();
app.setUpdateUser(updateUser); if (T.BooleanUtil.and(
T.ObjectUtil.isNotEmpty(names),
!Arrays.asList(names).contains(applicationName))) {
continue;
}
return app; 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);
@Override ApplicationEntity application = T.JSONUtil.toBean(metaJsonStr, ApplicationEntity.class);
public Page queryList(Map<String, Object> params) { application.setName(applicationName);
Page page = new Query(ApplicationEntity.class).getPage(params); resultList.add(application);
List<ApplicationEntity> packageList = this.getBaseMapper().queryList(page, params); break;
page.setRecords(packageList); }
return page; case "signature.json": {
} ObjectLoader loader = repository.open(treeWalk.getObjectId(0));
signatureMapping.put(applicationName, T.StrUtil.utf8Str(loader.getBytes()));
break;
}
default:
break;
}
}
private void validateParam(ApplicationEntity entity, boolean isUpdate) { for (ApplicationEntity entity : resultList) {
ApplicationEntity one = this.getOne(new LambdaQueryWrapper<ApplicationEntity>() String name = entity.getName();
.eq(ApplicationEntity::getWorkspaceId, entity.getWorkspaceId()) String signature = signatureMapping.getOrDefault(name, "");
.eq(ApplicationEntity::getName, entity.getName())); if (T.StrUtil.isNotEmpty(signature)) {
JSONObject jsonObject = T.JSONUtil.parseObj(signature);
if (T.ObjectUtil.isNotNull(one) && !isUpdate || T.ObjectUtil.isNotNull(one) && isUpdate && !T.StrUtil.equals(entity.getId(), one.getId())) { entity.setSignature(jsonObject);
throw ASWException.builder().rcode(RCode.APP_DUPLICATE_RECORD).build(); }
} }
} catch (IOException e) {
// package name format log.error(e, "[queryList] [error] [workspaceId: {}] [branch: {}]", workspaceId, branch);
if (T.ObjectUtil.isNotEmpty(entity.getPackageName()) && !T.JSONUtil.isTypeJSON(entity.getPackageName())) { throw new RuntimeException(e);
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();
} }
} }
return resultList;
// 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();
}
} }
@Override public void saveOrUpdateBatch(String workspaceId, String branch, String commitMessage, List<ApplicationEntity> list) {
@Transactional(rollbackFor = Exception.class) try (Git git = gitService.getGitInstance(workspaceId);
public ApplicationEntity saveApplication(ApplicationEntity entity) { Repository repository = git.getRepository();
RevWalk revWalk = new RevWalk(repository)) {
this.validateParam(entity, false); ObjectId branchRef = repository.resolve(branch);
RevTree revTree = revWalk.parseTree(branchRef);
// save // 先查询,区分 新增APP、修改APP
entity.setCreateTimestamp(System.currentTimeMillis()); List<ApplicationEntity> addAppList = T.ListUtil.list(true);
entity.setUpdateTimestamp(System.currentTimeMillis()); List<ApplicationEntity> updateAppList = T.ListUtil.list(true);
entity.setCreateUserId(StpUtil.getLoginIdAsString()); try (TreeWalk treeWalk = new TreeWalk(repository)) {
entity.setUpdateUserId(StpUtil.getLoginIdAsString()); treeWalk.addTree(revTree);
this.save(entity); 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);
}
});
}
if (T.ObjectUtil.isNotEmpty(entity.getSignature())){ // 修改文件路径信息
// save signature List<String> updateFilePath = T.ListUtil.list(true);
signatureService.saveSignature(entity.getSignature(), entity.getId()); 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"));
});
// 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
String filePath = T.StrUtil.concat(true, "applications/", entity.getName(), "/", fileName);
DirCacheEntry dirCacheEntry = new DirCacheEntry(filePath);
dirCacheEntry.setFileMode(FileMode.REGULAR_FILE);
ObjectId blobId = gitService.insertBlobFileToDatabase(repository, fileContent.getBytes());
dirCacheEntry.setObjectId(blobId);
newTreeBuilder.add(dirCacheEntry);
}
}
// 修改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);
// 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();
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);
}
} catch (IOException | ConcurrentRefUpdateException e) {
log.error(e, "[saveOrUpdateBatch] [error] [workspaceId: {}] [branch: {}]", workspaceId, branch);
throw new RuntimeException(e);
} }
if (T.ObjectUtil.isNotEmpty(entity.getNote())){
//save note
noteService.saveNote(entity.getNote(), entity.getId());
}
return entity;
}
@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());
}
if (T.ObjectUtil.isNotEmpty(entity.getNote())){
//save note
noteService.saveNote(entity.getNote(), entity.getId());
}
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 @Override
@@ -251,7 +222,7 @@ public class ApplicationServiceImpl extends ServiceImpl<ApplicationDao, Applicat
try { try {
switch (format) { switch (format) {
case "tsg2402": { 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)); JSON json = new JSONObject(m, JSONConfig.create().setIgnoreNullValue(false).setKeyComparator(String::compareToIgnoreCase));
return T.StrUtil.bytes(json.toJSONString(0)); return T.StrUtil.bytes(json.toJSONString(0));
} }
@@ -266,12 +237,15 @@ public class ApplicationServiceImpl extends ServiceImpl<ApplicationDao, Applicat
} }
@Override @Override
@Transactional(rollbackFor = Exception.class) public List<ApplicationEntity> importAppByFormat(String workspaceId, String branchName, String format, List<JSONObject> dataList) {
public List<ApplicationEntity> importAppByFormat(String workspaceId, String format, List<JSONObject> dataList) {
try { try {
switch (format) { switch (format) {
case "tsg2402": { 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; return records;
} }
default: default:

View File

@@ -151,15 +151,11 @@ public class GitServiceImpl implements IGitService {
Repository repository = git.getRepository(); Repository repository = git.getRepository();
ObjectInserter inserter = repository.getObjectDatabase().newInserter(); 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(); DirCache dirCache = DirCache.newInCore();
DirCacheBuilder builder = dirCache.builder(); DirCacheBuilder builder = dirCache.builder();
ObjectId objectId = this.insertBlobFileToDatabase(repository, "".getBytes());
DirCacheEntry entry = this.buildDirCacheEntry("README.md", FileMode.REGULAR_FILE, objectId);
builder.add(entry); builder.add(entry);
builder.finish(); builder.finish();
@@ -727,9 +723,7 @@ public class GitServiceImpl implements IGitService {
DirCache newTree = DirCache.newInCore(); DirCache newTree = DirCache.newInCore();
DirCacheBuilder newTreeBuilder = newTree.builder(); DirCacheBuilder newTreeBuilder = newTree.builder();
while (treeWalk.next()) { while (treeWalk.next()) {
DirCacheEntry entry = new DirCacheEntry(treeWalk.getPathString()); DirCacheEntry entry = this.buildDirCacheEntry(treeWalk.getPathString(), treeWalk.getFileMode(0), treeWalk.getObjectId(0));
entry.setFileMode(treeWalk.getFileMode(0));
entry.setObjectId(treeWalk.getObjectId(0));
newTreeBuilder.add(entry); newTreeBuilder.add(entry);
} }
@@ -739,9 +733,7 @@ public class GitServiceImpl implements IGitService {
ObjectId blobId = entry.getValue(); ObjectId blobId = entry.getValue();
// add file ref // add file ref
DirCacheEntry dirCacheEntry = new DirCacheEntry(filePath); DirCacheEntry dirCacheEntry = this.buildDirCacheEntry(filePath, FileMode.REGULAR_FILE, blobId);
dirCacheEntry.setFileMode(FileMode.REGULAR_FILE);
dirCacheEntry.setObjectId(blobId);
newTreeBuilder.add(dirCacheEntry); newTreeBuilder.add(dirCacheEntry);
} }
@@ -777,9 +769,7 @@ public class GitServiceImpl implements IGitService {
while (treeWalk.next()) { while (treeWalk.next()) {
String pathString = treeWalk.getPathString(); String pathString = treeWalk.getPathString();
if (!pathString.startsWith(appFilePrefixStr)) { if (!pathString.startsWith(appFilePrefixStr)) {
DirCacheEntry entry = new DirCacheEntry(pathString); DirCacheEntry entry = this.buildDirCacheEntry(pathString, treeWalk.getFileMode(0), treeWalk.getObjectId(0));
entry.setFileMode(treeWalk.getFileMode(0));
entry.setObjectId(treeWalk.getObjectId(0));
newTreeBuilder.add(entry); newTreeBuilder.add(entry);
} }
} }
@@ -854,9 +844,7 @@ public class GitServiceImpl implements IGitService {
String pathString = treeWalk.getPathString(); String pathString = treeWalk.getPathString();
// 先删 // 先删
if (!updateFilePath.contains(pathString)) { if (!updateFilePath.contains(pathString)) {
DirCacheEntry entry = new DirCacheEntry(pathString); DirCacheEntry entry = this.buildDirCacheEntry(pathString, treeWalk.getFileMode(0), treeWalk.getObjectId(0));
entry.setFileMode(treeWalk.getFileMode(0));
entry.setObjectId(treeWalk.getObjectId(0));
newTreeBuilder.add(entry); newTreeBuilder.add(entry);
} }
} }
@@ -1122,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 读取文件内容 * 根据 path,objectId 读取文件内容
* 响应 Map,key=encoding,content * 响应 Map,key=encoding,content

View File

@@ -1,40 +1,31 @@
package net.geedge.asw.module.app.service.impl; package net.geedge.asw.module.app.service.impl;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.Validator; import cn.hutool.core.lang.Validator;
import cn.hutool.json.JSONArray; import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import cn.hutool.log.Log; import cn.hutool.log.Log;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import net.geedge.asw.common.util.T; import net.geedge.asw.common.util.T;
import net.geedge.asw.module.app.entity.ApplicationEntity; 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.app.service.ITSGApplicationService;
import net.geedge.asw.module.attribute.entity.AttributeEntity; import net.geedge.asw.module.attribute.entity.AttributeEntity;
import net.geedge.asw.module.attribute.service.IAttributeService; import net.geedge.asw.module.attribute.service.IAttributeService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; 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; import java.util.stream.Collectors;
@Service @Service("tsg2402ApplicationService")
public class TSGApplicationServiceImpl implements ITSGApplicationService { public class TSG2402ApplicationServiceImpl implements ITSGApplicationService {
private static final Log log = Log.get(); private static final Log log = Log.get();
@Autowired @Autowired
private IAttributeService attributeService; private IAttributeService attributeService;
@Autowired
private IApplicationService applicationService;
@Autowired
private IApplicationSignatureService applicationSignatureService;
@Override @Override
public Map<Object, Object> aswToTsg2402(List<ApplicationEntity> appList) { public Map<Object, Object> aswToTsg2402(List<ApplicationEntity> appList) {
@@ -63,12 +54,11 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
Map properties = (Map) app.getProperties(); Map properties = (Map) app.getProperties();
Map<Object, Object> app_properties = T.MapUtil.builder() Map<Object, Object> app_properties = T.MapUtil.builder()
.put("parent_app_id", 0) .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("category", T.MapUtil.getStr(properties, "category", ""))
.put("subcategory", T.MapUtil.getStr(properties, "subcategory", "")) .put("subcategory", T.MapUtil.getStr(properties, "subcategory", ""))
.put("content", T.MapUtil.getStr(properties, "content", "")) .put("content", T.MapUtil.getStr(properties, "content", ""))
.put("risk", T.MapUtil.getStr(properties, "risk", "1")) .put("risk", T.MapUtil.getStr(properties, "risk", "1"))
.put("characteristics", T.MapUtil.getStr(properties, "characteristics", ""))
.put("deny_action", T.MapUtil.builder() .put("deny_action", T.MapUtil.builder()
.put("method", "drop") .put("method", "drop")
.put("after_n_packets", 0) .put("after_n_packets", 0)
@@ -85,8 +75,7 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
application.put("app_properties", app_properties); application.put("app_properties", app_properties);
// app_surrogates // app_surrogates
ApplicationSignatureEntity signature = applicationSignatureService.queryLastVersionSignatureByAppId(app.getId()); JSONObject jsonObject = (JSONObject) app.getSignature();
JSONObject jsonObject = T.JSONUtil.parseObj(signature.getContent());
JSONArray surrogates = jsonObject.getJSONArray("surrogates"); JSONArray surrogates = jsonObject.getJSONArray("surrogates");
if (!surrogates.isEmpty()) { if (!surrogates.isEmpty()) {
List<Map> app_surrogates = T.ListUtil.list(true); 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; int sig_object_id = 10, signature_id = 0;
for (ApplicationEntity app : appList) { for (ApplicationEntity app : appList) {
ApplicationSignatureEntity signature = applicationSignatureService.queryLastVersionSignatureByAppId(app.getId()); JSONObject jsonObject = (JSONObject) app.getSignature();
JSONObject jsonObject = T.JSONUtil.parseObj(signature.getContent());
JSONArray surrogates = jsonObject.getJSONArray("surrogates"); JSONArray surrogates = jsonObject.getJSONArray("surrogates");
List<Object> signaturesForApp = surrogates.stream() List<Object> signaturesForApp = surrogates.stream()
.map(obj -> ((JSONObject) obj).getJSONArray("signatures")) .map(obj -> ((JSONObject) obj).getJSONArray("signatures"))
@@ -160,56 +148,64 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
List<Integer> source_object_ids = T.ListUtil.list(true); List<Integer> source_object_ids = T.ListUtil.list(true);
// sig_objects // objects
JSONArray items = conditionJSONObj.getJSONArray("items"); JSONArray objects = conditionJSONObj.getJSONArray("objects");
for (Object tempObject : objects) {
JSONObject tempJsonObject = (JSONObject) tempObject;
String conditionType = attributeEntity.getObjectType(); // sig_objects
if ("application".equalsIgnoreCase(conditionType)) { JSONArray items = tempJsonObject.getJSONArray("items");
continue; String objectName = tempJsonObject.getStr("name");
} else if ("boolean".equals(conditionType)) { String objectType = tempJsonObject.getStr("type");
items.stream() String objectDescription = tempJsonObject.getStr("description");
.map(obj -> (JSONObject) obj)
.forEach(item -> {
String itemValue = T.MapUtil.getStr((JSONObject) item, "item");
if ("True".equalsIgnoreCase(itemValue)) {
source_object_ids.add(2);
} else if ("False".equalsIgnoreCase(itemValue)) {
source_object_ids.add(3);
}
});
} else if ("ip_protocol".equals(conditionType)) {
items.stream()
.map(obj -> (JSONObject) obj)
.forEach(item -> {
String itemValue = T.MapUtil.getStr((JSONObject) item, "item");
if ("ICMP".equalsIgnoreCase(itemValue)) {
source_object_ids.add(5);
} else if ("TCP".equalsIgnoreCase(itemValue)) {
source_object_ids.add(6);
} else if ("UDP".equalsIgnoreCase(itemValue)) {
source_object_ids.add(7);
}
});
} 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("sub_type", attributeEntity.getType())
.put("member_type", "item")
.put("uuid", T.IdUtil.fastSimpleUUID())
.put("statistics_option", "none")
.build();
Map<Object, Object> member = this.buildTSG2402SignaturesMember(attributeEntity, items); if ("application".equalsIgnoreCase(objectType)) {
sig_object.put("member", member); continue;
} else if ("boolean".equals(objectType)) {
items.stream()
.map(obj -> (JSONObject) obj)
.forEach(item -> {
String itemValue = T.MapUtil.getStr((JSONObject) item, "item");
if ("True".equalsIgnoreCase(itemValue)) {
source_object_ids.add(2);
} else if ("False".equalsIgnoreCase(itemValue)) {
source_object_ids.add(3);
}
});
} else if ("ip_protocol".equals(objectType)) {
items.stream()
.map(obj -> (JSONObject) obj)
.forEach(item -> {
String itemValue = T.MapUtil.getStr((JSONObject) item, "item");
if ("ICMP".equalsIgnoreCase(itemValue)) {
source_object_ids.add(5);
} else if ("TCP".equalsIgnoreCase(itemValue)) {
source_object_ids.add(6);
} else if ("UDP".equalsIgnoreCase(itemValue)) {
source_object_ids.add(7);
}
});
} else {
Map<Object, Object> sig_object = T.MapUtil.builder()
.put("id", sig_object_id)
.put("source_id", sig_object_id)
.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();
sig_objects.add(sig_object); Map<Object, Object> member = this.buildTSG2402SignaturesMember(objectType.toLowerCase(), items);
source_object_ids.add(sig_object_id); sig_object.put("member", member);
sig_object_id++;
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); or_condition_obj.put("source_object_ids", source_object_ids);
@@ -303,12 +299,11 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
return m; 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); List<Object> list = T.ListUtil.list(true);
itemArr.stream() itemArr.stream()
.map(obj -> (JSONObject) obj) .map(obj -> (JSONObject) obj)
.forEach(item -> { .forEach(item -> {
String objectType = attributeEntity.getObjectType().toLowerCase();
switch (objectType) { switch (objectType) {
case "keywords": case "keywords":
case "http_signature": { case "http_signature": {
@@ -484,7 +479,6 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@Override @Override
@Transactional(rollbackFor = Exception.class)
public List<ApplicationEntity> tsg2402ToAsw(String workspaceId, List<JSONObject> dataList) { public List<ApplicationEntity> tsg2402ToAsw(String workspaceId, List<JSONObject> dataList) {
List<ApplicationEntity> records = T.ListUtil.list(true); List<ApplicationEntity> records = T.ListUtil.list(true);
for (JSONObject tsgAppSourceData : dataList) { for (JSONObject tsgAppSourceData : dataList) {
@@ -497,46 +491,42 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
.map(obj -> (JSONObject) obj) .map(obj -> (JSONObject) obj)
.forEach(application -> { .forEach(application -> {
// application // application
String app_id = application.getStr("app_id");
String app_name = application.getStr("app_name"); String app_name = application.getStr("app_name");
String app_longname = application.getStr("app_longname");
String description = application.getStr("description"); String description = application.getStr("description");
JSONObject appProperties = application.getJSONObject("app_properties"); JSONObject appProperties = application.getJSONObject("app_properties");
String category = T.MapUtil.getStr(appProperties, "category", ""); String category = T.MapUtil.getStr(appProperties, "category", "");
String subcategory = T.MapUtil.getStr(appProperties, "subcategory", ""); String subcategory = T.MapUtil.getStr(appProperties, "subcategory", "");
String content = T.MapUtil.getStr(appProperties, "content", ""); 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); int risk = T.MapUtil.getInt(appProperties, "risk", 1);
String characteristics = T.MapUtil.getStr(appProperties, "characteristics", "");
Map<Object, Object> properties = T.MapUtil.builder() Map<Object, Object> properties = T.MapUtil.builder()
.put("category", category) .put("category", category)
.put("subcategory", subcategory) .put("subcategory", subcategory)
.put("content", content) .put("content", content)
.put("parentApp", parent_app_name)
.put("risk", risk) .put("risk", risk)
.put("characteristics", characteristics)
.build(); .build();
// save or update application // meta.json
ApplicationEntity entity = new ApplicationEntity(); ApplicationEntity entity = new ApplicationEntity();
entity.setId(app_id);
entity.setName(app_name); entity.setName(app_name);
entity.setLongName(app_longname);
entity.setDescription(description); entity.setDescription(description);
entity.setProperties(properties); entity.setProperties(properties);
entity.setPackageName("{}"); // default value
entity.setWorkspaceId(workspaceId); entity.setDeveloper("");
entity.setCreateTimestamp(System.currentTimeMillis()); entity.setWebsite("");
entity.setUpdateTimestamp(System.currentTimeMillis()); entity.setPackageName(
entity.setCreateUserId(StpUtil.getLoginIdAsString()); T.MapUtil.builder()
entity.setUpdateUserId(StpUtil.getLoginIdAsString()); .put("android", "")
.put("ios", "")
ApplicationEntity one = applicationService.getOne(new LambdaQueryWrapper<ApplicationEntity>() .build()
.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();
// surrogate - signature // surrogate - signature
Map<String, List<String>> surrAndSignListMap = T.MapUtil.newHashMap(); Map<String, List<String>> surrAndSignListMap = T.MapUtil.newHashMap();
@@ -549,7 +539,6 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
} }
} }
List<Object> insertSurrogateList = T.ListUtil.list(true); List<Object> insertSurrogateList = T.ListUtil.list(true);
for (Map.Entry<String, List<String>> entry : surrAndSignListMap.entrySet()) { for (Map.Entry<String, List<String>> entry : surrAndSignListMap.entrySet()) {
String surrogateName = entry.getKey(); String surrogateName = entry.getKey();
@@ -575,19 +564,11 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
.put("surrogates", insertSurrogateList) .put("surrogates", insertSurrogateList)
.build(); .build();
// save application signatrue // signature.json
ApplicationSignatureEntity signatureEntity = new ApplicationSignatureEntity(); entity.setSignature(T.JSONUtil.parseObj(sm));
signatureEntity.setApplicationId(applicationId);
signatureEntity.setContent(T.JSONUtil.toJsonStr(sm));
signatureEntity.setCreateTimestamp(System.currentTimeMillis());
signatureEntity.setCreateUserId(StpUtil.getLoginIdAsString());
signatureEntity.setOpVersion(0L);
ApplicationSignatureEntity signatureLast = applicationSignatureService.queryLastVersionSignatureByAppId(applicationId); // add records
if (T.ObjectUtil.isNotEmpty(signatureLast)) { records.add(entity);
signatureEntity.setOpVersion(signatureLast.getOpVersion() + 1);
}
applicationSignatureService.save(signatureEntity);
}); });
} }
return records; return records;
@@ -642,20 +623,10 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
}) })
.collect(Collectors.toList()); .collect(Collectors.toList());
List<Map<Object, Object>> itemList = this.buildAswConditionItemsFromTSG2402(sourceObjectList); List<Map<Object, Object>> objects = this.buildAswConditionObjectsFromTSG2402(sourceObjectList);
if (T.CollUtil.isEmpty(itemList)) continue; if (T.CollUtil.isEmpty(objects)) continue;
// item value 去重 m.put("objects", objects);
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);
conditionMapList.add(m); conditionMapList.add(m);
} }
@@ -667,14 +638,17 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
return surrogate; return surrogate;
} }
private List<Map<Object, Object>> buildAswConditionItemsFromTSG2402(List<JSONObject> sourceObjectList) { private List<Map<Object, Object>> buildAswConditionObjectsFromTSG2402(List<JSONObject> sourceObjectList) {
List<Map<Object, Object>> iiemList = T.ListUtil.list(true); List<Map<Object, Object>> objectList = T.ListUtil.list(true);
for (JSONObject jsonObject : sourceObjectList) { for (JSONObject jsonObject : sourceObjectList) {
String name = jsonObject.getStr("name");
String type = jsonObject.getStr("type"); String type = jsonObject.getStr("type");
String description = jsonObject.getStr("description");
JSONArray itemArr = (JSONArray) T.JSONUtil.getByPath(jsonObject, "member.items"); JSONArray itemArr = (JSONArray) T.JSONUtil.getByPath(jsonObject, "member.items");
itemArr = T.CollUtil.defaultIfEmpty(itemArr, new JSONArray()); itemArr = T.CollUtil.defaultIfEmpty(itemArr, new JSONArray());
List<Map<Object, Object>> items = T.ListUtil.list(true);
switch (type) { switch (type) {
case "http_signature": case "http_signature":
case "keywords": { case "keywords": {
@@ -727,7 +701,7 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
if (T.StrUtil.isNotEmpty(context_name)) { if (T.StrUtil.isNotEmpty(context_name)) {
m.put("district", context_name); m.put("district", context_name);
} }
iiemList.add(m); items.add(m);
}); });
break; break;
} }
@@ -737,7 +711,7 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
.map(obj -> (JSONObject) obj) .map(obj -> (JSONObject) obj)
.forEach(item -> { .forEach(item -> {
String str = (String) T.JSONUtil.getByPath(item, "string.patterns[0].keywords"); String str = (String) T.JSONUtil.getByPath(item, "string.patterns[0].keywords");
iiemList.add( items.add(
T.MapUtil.builder() T.MapUtil.builder()
.put("item", str) .put("item", str)
.put("description", "") .put("description", "")
@@ -761,7 +735,7 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
if (!"0-65535" .equalsIgnoreCase(port)) { if (!"0-65535" .equalsIgnoreCase(port)) {
ipAddress = T.StrUtil.concat(true, ipAddress, "#", port); ipAddress = T.StrUtil.concat(true, ipAddress, "#", port);
} }
iiemList.add( items.add(
T.MapUtil.builder() T.MapUtil.builder()
.put("item", ipAddress) .put("item", ipAddress)
.put("description", "") .put("description", "")
@@ -778,7 +752,7 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
if (T.StrUtil.isEmpty(port)) { if (T.StrUtil.isEmpty(port)) {
port = (String) T.JSONUtil.getByPath(item, "port.port_range"); port = (String) T.JSONUtil.getByPath(item, "port.port_range");
} }
iiemList.add( items.add(
T.MapUtil.builder() T.MapUtil.builder()
.put("item", port) .put("item", port)
.put("description", "") .put("description", "")
@@ -797,7 +771,7 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
.put("item", low_boundary + "-" + up_boundary) .put("item", low_boundary + "-" + up_boundary)
.put("description", "") .put("description", "")
.build(); .build();
iiemList.add(m); items.add(m);
}); });
break; break;
} }
@@ -807,7 +781,7 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
.put("item", jsonObject.getStr("name")) .put("item", jsonObject.getStr("name"))
.put("description", "") .put("description", "")
.build(); .build();
iiemList.add(m); items.add(m);
break; break;
} }
case "application": { case "application": {
@@ -816,8 +790,28 @@ public class TSGApplicationServiceImpl implements ITSGApplicationService {
default: default:
break; 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;
} }
} }