feat: ASW-62 Environment session 停止捕包接口开发

This commit is contained in:
zhangshuai
2024-09-09 14:47:29 +08:00
parent b037e46f8e
commit 3ec0a33d3a
4 changed files with 120 additions and 5 deletions

View File

@@ -73,4 +73,6 @@ public class Constants {
* env api websocket path
*/
public static final String ENV_API_WEBSOCKET_PATH = "/api/v1/env/websocket";
public static final String ENV_API_TCPDUMP_PATH = "/api/v1/env/pcap";
}

View File

@@ -1,5 +1,7 @@
package net.geedge.asw.module.environment.controller;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
@@ -15,12 +17,20 @@ import net.geedge.asw.module.environment.entity.EnvironmentSessionEntity;
import net.geedge.asw.module.environment.service.IEnvironmentService;
import net.geedge.asw.module.environment.service.IEnvironmentSessionService;
import net.geedge.asw.module.environment.util.EnvironmentUtil;
import net.geedge.asw.module.runner.entity.PcapEntity;
import net.geedge.asw.module.runner.service.IPcapService;
import net.geedge.asw.module.runner.util.RunnerConstant;
import net.geedge.asw.module.sys.service.ISysUserService;
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.http.*;
import org.springframework.web.bind.annotation.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
@RestController
@@ -42,6 +52,9 @@ public class EnvironmentController {
@Autowired
private IWorkspaceService workspaceService;
@Autowired
private IPcapService pcapService;
@GetMapping("/{id}")
public R detail(@PathVariable("id") String id) {
EnvironmentEntity entity = environmentService.queryInfo(id);
@@ -148,4 +161,55 @@ public class EnvironmentController {
environmentSessionService.updateById(session);
return R.ok();
}
@DeleteMapping("/{envId}/session/{sessionId}/pcap/{pcapId}")
public void stopTcpdump(@PathVariable("envId") String envId,
@PathVariable("sessionId") String sessionId,
@PathVariable("pcapId") String pcapId,
@RequestParam Map param,
HttpServletResponse response) throws IOException, ServletException {
EnvironmentSessionEntity session = environmentSessionService.getOne(new LambdaQueryWrapper<EnvironmentSessionEntity>().eq(EnvironmentSessionEntity::getId, sessionId).eq(EnvironmentSessionEntity::getStatus, 1));
if (T.ObjectUtil.isNull(session)){
throw new ASWException(RCode.ENVIRONMENT_SESSION_NOT_EXIST);
}
EnvironmentEntity environment = environmentService.getById(envId);
if (T.ObjectUtil.isNull(environment)) {
throw new ASWException(RCode.ENVIRONMENT_NOT_EXIST);
}
// build query param
Map params = T.MapUtil.builder().put("id", pcapId).put("returnFile", true).build();
ResponseEntity<byte[]> responseEntity = EnvironmentUtil.stopTcpdump(environment, params);
if (ObjectUtil.isNotNull(param.get("savePcap"))){
// save pcap to workspace
WorkspaceEntity workspace = workspaceService.getById(session.getWorkspaceId());
String pcapName = T.StrUtil.emptyToDefault(param.get("pcapName").toString(), pcapId);
File destination = T.FileUtil.file(T.WebPathUtil.getRootPath(), workspace.getId(), T.StrUtil.concat(true,pcapName, ".pcap"));
if (destination.exists()){
String formatTime = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
destination = T.FileUtil.file(T.WebPathUtil.getRootPath(), workspace.getId(), T.StrUtil.concat(true, pcapName, "-", formatTime, ".pcap"));
}
FileOutputStream fos = new FileOutputStream(destination);
fos.write(responseEntity.getBody());
fos.flush();
fos.close();
log.info("save pcap to path:{}", destination.getAbsolutePath());
// save entity
PcapEntity entity = new PcapEntity();
entity.setId(pcapId);
entity.setName(destination.getName());
entity.setSize(destination.length());
entity.setStatus(RunnerConstant.PcapStatus.UPLOADED.getValue());
entity.setCreateTimestamp(System.currentTimeMillis());
entity.setCreateUserId(StpUtil.getLoginIdAsString());
entity.setWorkspaceId(workspace.getId());
entity.setPath(destination.getPath());
entity.setMd5(T.DigestUtil.md5Hex(destination));
pcapService.save(entity);
response.getWriter().write(T.JSONUtil.toJsonStr(R.ok()));
}else {
EnvironmentUtil.writeResponseWithHeaders(response, responseEntity);
}
}
}

View File

@@ -38,9 +38,54 @@ public class EnvironmentUtil {
private static Log log = Log.get();
private static RestTemplate restTemplate;
/**
* agent stop tcpdump
* @param environment
* @param params
* @return
* @throws IOException
* @throws ServletException
*/
public static ResponseEntity<byte[]> stopTcpdump(EnvironmentEntity environment, Map params) throws IOException, ServletException {
JSONObject jsonObject = environment.getParamJSONObject();
String url = jsonObject.getStr("url");
String token = jsonObject.getStr("token");
String urlStr = UrlBuilder.of(url)
.setPath(UrlPath.of(Constants.ENV_API_TCPDUMP_PATH, Charset.forName("UTF-8")))
.setQuery(UrlQuery.of(params))
.setCharset(StandardCharsets.UTF_8).toString();
// token
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.AUTHORIZATION, token);
HttpEntity httpEntity = new HttpEntity(headers);
ResponseEntity<byte[]> responseEntity = null;
try {
responseEntity = restTemplate.exchange(new URI(urlStr), HttpMethod.DELETE, httpEntity, byte[].class);
} catch (Exception e) {
log.error(e, "stop tcpdump request error. url:{}", urlStr);
String message = e.getMessage();
if (ObjectUtil.isNotNull(e.getCause())) {
message = e.getCause().getMessage();
}
throw new ASWException(message, HttpStatus.INTERNAL_SERVER_ERROR.value());
}
int statusCode = responseEntity.getStatusCodeValue();
log.info("stop tcpdump request url:{}, responseStatus:{}", urlStr, statusCode);
return responseEntity;
}
/**
* env api agent
* @param device
* @param request
* @param response
* @param sessionId
* @throws IOException
* @throws ServletException
*/
public static void getForObject(EnvironmentEntity device, HttpServletRequest request, HttpServletResponse response, String sessionId) throws IOException, ServletException {
// path
String pathProfix = T.StrUtil.concat(true, Constants.ENV_API_PREFIX, "/", device.getId());
String[] paths = request.getServletPath().split(sessionId);
String path = Arrays.asList(paths).getLast();
path = path.startsWith("/") ? (String.format("%s%s", Constants.ENV_API_PREFIX, path))
@@ -113,11 +158,13 @@ public class EnvironmentUtil {
}
throw new ASWException(message, HttpStatus.INTERNAL_SERVER_ERROR.value());
}
log.info("env request url:{}, responseStatus:{}", urlStr, responseEntity.getStatusCode());
writeResponseWithHeaders(response, responseEntity);
}
public static void writeResponseWithHeaders(HttpServletResponse response, ResponseEntity<byte[]> responseEntity) throws IOException {
HttpHeaders httpHeaders = responseEntity.getHeaders();
int statusCode = responseEntity.getStatusCodeValue();
log.info("env request url:{}, responseStatus:{}", urlStr, statusCode);
byte[] responseBody = responseEntity.getBody();
response.reset();
response.setStatus(statusCode);

View File

@@ -10,6 +10,8 @@ spring:
no-cache: true
# max-age: 30d
# cache-public: true
jackson:
default-property-inclusion: non_empty
profiles:
active: prod
include: magic-api
@@ -26,7 +28,7 @@ spring:
baseline-on-migrate: true # 连接数据库中存在表时设置为true
locations: classpath:db/migration # 脚本路径
clean-disabled: false # flyway 的 clean 命令会删除指定 schema 下的所有 table, 生产务必禁掉。这个默认值是 false 理论上作为默认配置是不科学的
validate-on-migrate: true # 执行迁移时是否自动调用验证 当你的 版本不符合逻辑 比如 你先执行了 DML 而没有 对应的DDL 会抛出异常
validate-on-migrate: false # 执行迁移时是否自动调用验证 当你的 版本不符合逻辑 比如 你先执行了 DML 而没有 对应的DDL 会抛出异常
placeholder-replacement: false # 不做取值替换 默认替换为 ${} 初始化sql中有sql语句存在freemarker替换所以禁用此项
servlet:
multipart:
@@ -71,4 +73,4 @@ mybatis-plus:
banner: false
logging:
config: ./config/logback-spring.xml
config: D:\IdeaProjects\asw-controller\src\main\resources\config\logback-spring.xml