feat: ASW-62 Environment session 停止捕包接口开发
This commit is contained in:
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user