feat:ASW-56 device 我的设备 接口开发

1.调整 device 接口 path
2.调整 device  替换成 environment
This commit is contained in:
zhangshuai
2024-09-04 10:59:42 +08:00
parent 1d0b3c6c9b
commit fec4beed2d
28 changed files with 526 additions and 346 deletions

View File

@@ -3,10 +3,13 @@ package net.geedge.asw.common.config.websocket;
import cn.hutool.json.JSONObject;
import cn.hutool.log.Log;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import net.geedge.asw.common.util.Constants;
import net.geedge.asw.common.util.T;
import net.geedge.asw.module.device.entity.DeviceEntity;
import net.geedge.asw.module.device.service.IDeviceService;
import net.geedge.asw.module.environment.entity.EnvironmentEntity;
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 org.springframework.stereotype.Component;
import org.springframework.web.socket.*;
import org.springframework.web.socket.handler.TextWebSocketHandler;
@@ -19,28 +22,37 @@ import java.nio.ByteBuffer;
import java.util.concurrent.CompletionStage;
@Component
public class DeviceWebSocketHandler extends TextWebSocketHandler {
public class EnvironmentWebSocketHandler extends TextWebSocketHandler {
private static final Log log = Log.get();
/**
* device id
* env id
*/
private String id;
private String envId;
/**
* device token
* session
*/
private String sessionId;
/**
* env token
*/
private String token;
private IDeviceService deviceService;
private IEnvironmentService environmentService;
public DeviceWebSocketHandler(IDeviceService deviceService) {
this.deviceService = deviceService;
private IEnvironmentSessionService environmentSessionService;
public EnvironmentWebSocketHandler(IEnvironmentService environmentService, IEnvironmentSessionService environmentSessionService) {
this.environmentService = environmentService;
this.environmentSessionService = environmentSessionService;
}
private void initFieldVal(WebSocketSession session) {
this.id = (String) session.getAttributes().get("id");
this.envId = (String) session.getAttributes().get("envId");
this.sessionId = (String) session.getAttributes().get("sessionId");
this.token = (String) session.getAttributes().get("token");
}
@@ -49,28 +61,36 @@ public class DeviceWebSocketHandler extends TextWebSocketHandler {
super.afterConnectionEstablished(session);
this.initFieldVal(session);
log.info("WebSocket connectioned. after connection established open device begin... device id: {}", id);
log.info("WebSocket connectioned. after connection established open env begin... env id: {}", envId);
DeviceEntity deviceEntity = deviceService.queryInfo(id);
JSONObject paramJSONObject = deviceEntity.getParamJSONObject();
if (T.StrUtil.equals(token, paramJSONObject.getStr("token"))) {
log.warn("WebSocket connectioned error. device token exception. device id: {}, token: {}", id, token);
session.sendMessage(new TextMessage("Token error, Please config device token"));
EnvironmentSessionEntity environmentSession = environmentSessionService.getOne(new LambdaQueryWrapper<EnvironmentSessionEntity>().eq(EnvironmentSessionEntity::getId, sessionId).eq(EnvironmentSessionEntity::getStatus, 1));
if (environmentSession == null) {
log.warn("environment session does not exist. session id: {}", sessionId);
session.sendMessage(new TextMessage("environment session does not exist"));
session.close();
return;
}
String urlStr = String.format("ws://%s:%s%s", paramJSONObject.getStr("host"), paramJSONObject.getStr("port"), Constants.DEVICE_API_WEBSOCKET_PATH);
EnvironmentEntity deviceEntity = environmentService.queryInfo(envId);
JSONObject paramJSONObject = deviceEntity.getParamJSONObject();
if (T.StrUtil.equals(token, paramJSONObject.getStr("token"))) {
log.warn("WebSocket connectioned error. env token exception. env id: {}, token: {}", envId, token);
session.sendMessage(new TextMessage("Token error, Please config env token"));
session.close();
return;
}
String urlStr = String.format("%s%s", paramJSONObject.getStr("url"), Constants.DEVICE_API_WEBSOCKET_PATH);
urlStr = urlStr.replace("http", "ws");
HttpClient client = HttpClient.newHttpClient();
WebSocket webSocket = client.newWebSocketBuilder()
.buildAsync(URI.create(urlStr), new WebSocketListener(session))
.get();
log.info("[afterConnectionEstablished] [device server: {}]", T.JSONUtil.toJsonStr(paramJSONObject));
session.getAttributes().put("deviceWebsocket", webSocket);
log.info("[afterConnectionEstablished] [env server: {}]", T.JSONUtil.toJsonStr(paramJSONObject));
session.getAttributes().put("envWebsocket", webSocket);
}
@@ -97,7 +117,7 @@ public class DeviceWebSocketHandler extends TextWebSocketHandler {
@Override
public CompletionStage<?> onClose(WebSocket webSocket, int statusCode, String reason) {
log.info("Device webSocket connection closed, Status: " + statusCode + ", Reason: " + reason);
log.info("Env webSocket connection closed, Status: " + statusCode + ", Reason: " + reason);
return WebSocket.Listener.super.onClose(webSocket, statusCode, reason);
}
}
@@ -105,10 +125,10 @@ public class DeviceWebSocketHandler extends TextWebSocketHandler {
@Override
protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) {
try {
// asw -> device api
WebSocket vncSocket = (WebSocket) session.getAttributes().get("deviceWebsocket");
if (vncSocket != null) {
vncSocket.sendBinary(message.getPayload(), true);
// asw -> env api
WebSocket envSocket = (WebSocket) session.getAttributes().get("envWebsocket");
if (envSocket != null) {
envSocket.sendBinary(message.getPayload(), true);
}
} catch (Exception e) {
log.error(e, "[handleBinaryMessage] [error]");
@@ -118,9 +138,9 @@ public class DeviceWebSocketHandler extends TextWebSocketHandler {
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
log.info("[afterConnectionClosed] [WebSocket connection closed] [websocket uri: {}]", session.getUri());
WebSocket deviceWebsocket = (WebSocket) session.getAttributes().get("deviceWebsocket");
if (deviceWebsocket != null) {
deviceWebsocket.sendClose(WebSocket.NORMAL_CLOSURE, "Normal closure");
WebSocket envWebsocket = (WebSocket) session.getAttributes().get("envWebsocket");
if (envWebsocket != null) {
envWebsocket.sendClose(WebSocket.NORMAL_CLOSURE, "Normal closure");
}
super.afterConnectionClosed(session, status);
}

View File

@@ -1,6 +1,7 @@
package net.geedge.asw.common.config.websocket;
import net.geedge.asw.module.device.service.IDeviceService;
import net.geedge.asw.module.environment.service.IEnvironmentService;
import net.geedge.asw.module.environment.service.IEnvironmentSessionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
@@ -12,11 +13,14 @@ import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry
public class WebSocketConfig implements WebSocketConfigurer {
@Autowired
private IDeviceService deviceService;
private IEnvironmentService deviceService;
@Autowired
private IEnvironmentSessionService environmentSessionService;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new DeviceWebSocketHandler(deviceService), "/api/v1/device/{id}/novnc")
registry.addHandler(new EnvironmentWebSocketHandler(deviceService, environmentSessionService), "/api/v1/env/{envId}/session/{sessionId}/novnc")
.addInterceptors(new WebSocketInterceptor())
.setAllowedOrigins("*");
}

View File

@@ -1,6 +1,5 @@
package net.geedge.asw.common.config.websocket;
import jakarta.servlet.http.HttpSession;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
@@ -20,9 +19,10 @@ public class WebSocketInterceptor extends HttpSessionHandshakeInterceptor {
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
String servletPath = servletRequest.getServletRequest().getServletPath();
UriTemplate template = new UriTemplate("/api/v1/device/{id}/novnc");
UriTemplate template = new UriTemplate("/api/v1/env/{envId}/session/{sessionId}/novnc");
Map<String, String> variables = template.match(servletPath);
attributes.put("id", variables.get("id"));
attributes.put("envId", variables.get("envId"));
attributes.put("sessionId", variables.get("sessionId"));
attributes.put("token", servletRequest.getServletRequest().getParameter("token"));
}
return super.beforeHandshake(request, response, wsHandler, attributes);

View File

@@ -79,6 +79,12 @@ public enum RCode {
PCAP_UPLOAD_WEB_SHARK_ERROR(501001, "web shark upload pcap error"),
//environment
ENVIRONMENT_SESSION_NOT_EXIST(601001, "environment session does not exist"),
ENVIRONMENT_NOT_EXIST(601002, "environment does not exist"),
SUCCESS(200, "success"); // 成功
private RCode(Integer code, String msg) {

View File

@@ -1,16 +0,0 @@
package net.geedge.asw.module.device.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import net.geedge.asw.module.device.entity.DeviceEntity;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
import java.util.Map;
@Mapper
public interface DeviceDao extends BaseMapper<DeviceEntity> {
List<DeviceEntity> queryList(Page page, Map<String, Object> params);
}

View File

@@ -1,10 +0,0 @@
package net.geedge.asw.module.device.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import net.geedge.asw.module.device.entity.DeviceLogEntity;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface DeviceLogDao extends BaseMapper<DeviceLogEntity> {
}

View File

@@ -1,8 +0,0 @@
package net.geedge.asw.module.device.service;
import com.baomidou.mybatisplus.extension.service.IService;
import net.geedge.asw.module.device.entity.DeviceLogEntity;
public interface IDeviceLogService extends IService<DeviceLogEntity>{
}

View File

@@ -1,20 +0,0 @@
package net.geedge.asw.module.device.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import net.geedge.asw.module.device.entity.DeviceEntity;
import java.util.List;
import java.util.Map;
public interface IDeviceService extends IService<DeviceEntity>{
DeviceEntity queryInfo(String id);
Page queryList(Map<String, Object> params);
DeviceEntity saveDevice(DeviceEntity entity);
void removeDevice(List<String> ids);
}

View File

@@ -1,15 +0,0 @@
package net.geedge.asw.module.device.service.impl;
import cn.hutool.log.Log;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import net.geedge.asw.module.device.dao.DeviceLogDao;
import net.geedge.asw.module.device.entity.DeviceLogEntity;
import net.geedge.asw.module.device.service.IDeviceLogService;
import org.springframework.stereotype.Service;
@Service
public class DeviceLogServiceImpl extends ServiceImpl<DeviceLogDao, DeviceLogEntity> implements IDeviceLogService {
private static final Log log = Log.get();
}

View File

@@ -1,103 +0,0 @@
package net.geedge.asw.module.device.service.impl;
import cn.dev33.satoken.stp.StpUtil;
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.util.RCode;
import net.geedge.asw.common.util.T;
import net.geedge.asw.module.device.dao.DeviceDao;
import net.geedge.asw.module.device.entity.DeviceEntity;
import net.geedge.asw.module.device.entity.DeviceLogEntity;
import net.geedge.asw.module.device.service.IDeviceLogService;
import net.geedge.asw.module.device.service.IDeviceService;
import net.geedge.asw.module.sys.entity.SysUserEntity;
import net.geedge.asw.module.sys.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Map;
@Service
public class DeviceServiceImpl extends ServiceImpl<DeviceDao, DeviceEntity> implements IDeviceService {
private static final Log log = Log.get();
@Autowired
private ISysUserService sysUserService;
@Autowired
private IDeviceLogService deviceLogService;
@Override
public DeviceEntity queryInfo(String id) {
DeviceEntity device = this.getById(id);
T.VerifyUtil.is(device).notNull(RCode.SYS_RECORD_NOT_FOUND);
// param
device.setParam(device.getParamJSONObject());
SysUserEntity createUser = sysUserService.getById(device.getCreateUserId());
SysUserEntity updateUser = sysUserService.getById(device.getUpdateUserId());
device.setCreateUser(createUser);
device.setUpdateUser(updateUser);
DeviceLogEntity deviceLog = deviceLogService.getOne(new LambdaQueryWrapper<DeviceLogEntity>().eq(DeviceLogEntity::getDeviceId, device.getId()));
if (null != deviceLog) {
SysUserEntity useUser = sysUserService.getById(deviceLog.getUserId());
JSONObject jsonObject = new JSONObject();
jsonObject.set("id", useUser.getId());
jsonObject.set("name", useUser.getName());
jsonObject.set("startTimestamp", deviceLog.getStartTimestamp());
jsonObject.set("endTimestamp", deviceLog.getEndTimestamp());
device.setUseUser(jsonObject);
}
return device;
}
@Override
public Page queryList(Map<String, Object> params) {
Page page = T.PageUtil.getPage(params);
List<DeviceEntity> packageList = this.getBaseMapper().queryList(page, params);
for (DeviceEntity entity : packageList) {
entity.setParam(entity.getParamJSONObject());
}
page.setRecords(packageList);
return page;
}
@Override
public DeviceEntity saveDevice(DeviceEntity entity) {
// param
entity.setParam(entity.getParamStr());
// default android
entity.setPlatform(T.StrUtil.emptyToDefault(entity.getPlatform(), "android"));
entity.setCreateTimestamp(System.currentTimeMillis());
entity.setUpdateTimestamp(System.currentTimeMillis());
entity.setCreateUserId(StpUtil.getLoginIdAsString());
entity.setUpdateUserId(StpUtil.getLoginIdAsString());
// save
this.save(entity);
return entity;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void removeDevice(List<String> ids) {
// remove
this.removeBatchByIds(ids);
// log
deviceLogService.remove(new LambdaQueryWrapper<DeviceLogEntity>().in(DeviceLogEntity::getDeviceId, ids));
}
}

View File

@@ -1,40 +1,42 @@
package net.geedge.asw.module.device.controller;
package net.geedge.asw.module.environment.controller;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
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.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import net.geedge.asw.common.util.*;
import net.geedge.asw.module.device.entity.DeviceEntity;
import net.geedge.asw.module.device.service.IDeviceService;
import net.geedge.asw.module.device.util.DeviceUtil;
import net.geedge.asw.module.environment.entity.EnvironmentEntity;
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 org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;
import java.util.*;
@RestController
@RequestMapping("/api/v1/device")
public class DeviceController {
@RequestMapping("/api/v1/env")
public class EnvironmentController {
private static final Log log = Log.get();
@Autowired
private IDeviceService deviceService;
private IEnvironmentService environmentService;
@Autowired
private RestTemplate restTemplate;
private IEnvironmentSessionService environmentSessionService;
@GetMapping("/{id}")
public R detail(@PathVariable("id") String id) {
DeviceEntity entity = deviceService.queryInfo(id);
EnvironmentEntity entity = environmentService.queryInfo(id);
return R.ok().putData("record", entity);
}
@@ -42,42 +44,41 @@ public class DeviceController {
public R list(@RequestParam Map<String, Object> params) {
T.VerifyUtil.is(params).notNull()
.and(T.MapUtil.getStr(params, "workspaceId")).notEmpty(RCode.WORKSPACE_ID_CANNOT_EMPTY);
Page page = deviceService.queryList(params);
Page page = environmentService.queryList(params);
return R.ok(page);
}
@PostMapping
public R add(@RequestBody DeviceEntity entity) {
public R add(@RequestBody EnvironmentEntity entity) {
T.VerifyUtil.is(entity).notNull()
.and(entity.getName()).notEmpty(RCode.NAME_CANNOT_EMPTY)
.and(entity.getWorkspaceId()).notEmpty(RCode.WORKSPACE_ID_CANNOT_EMPTY);
DeviceEntity deviceEntity = deviceService.saveDevice(entity);
EnvironmentEntity deviceEntity = environmentService.saveDevice(entity);
return R.ok().putData("id", deviceEntity.getId());
}
@DeleteMapping
public R delete(String[] ids) {
T.VerifyUtil.is(ids).notEmpty();
deviceService.removeDevice(T.ListUtil.of(ids));
environmentService.removeDevice(T.ListUtil.of(ids));
return R.ok();
}
@PostMapping("/test")
public R testConnect(@RequestBody DeviceEntity entity) {
public R testConnect(@RequestBody EnvironmentEntity entity) {
T.VerifyUtil.is(entity).notNull()
.and(entity.getParam()).notEmpty(RCode.PARAM_CANNOT_EMPTY);
JSONObject jsonObject = entity.getParamJSONObject();
String host = jsonObject.getStr("host");
String port = jsonObject.getStr("port");
String url = jsonObject.getStr("url");
String token = jsonObject.getStr("token");
if (T.StrUtil.hasEmpty(host, port, token)) {
if (T.StrUtil.hasEmpty(url, token)) {
return R.error(RCode.PARAM_CANNOT_EMPTY);
}
try {
HttpRequest request = T.HttpUtil.createGet(String.format("http://%s:%s/api/v1/device/status", host, port));
HttpRequest request = T.HttpUtil.createGet(String.format("%s/api/v1/device/status", url));
request.header("Authorization", token);
HttpResponse response = request.execute();
log.info("[testConnect] [status: {}]", response.getStatus());
@@ -94,14 +95,24 @@ public class DeviceController {
return R.error(RCode.ERROR);
}
@RequestMapping(value = "/{id}/**", method ={ RequestMethod.GET, RequestMethod.POST, RequestMethod.DELETE}, headers = "Upgrade!=websocket")
public void deviceAgent(@PathVariable("id") String deviceId, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
DeviceEntity device = deviceService.getById(deviceId);
if (T.ObjectUtil.isNull(device)) {
throw new ASWException(RCode.SYS_RECORD_NOT_FOUND);
@RequestMapping(value = "/{envId}/session/{sessionId}/**", method ={ RequestMethod.GET, RequestMethod.POST, RequestMethod.DELETE}, headers = "Upgrade!=websocket")
public void agentEvn(@PathVariable("envId") String envId, @PathVariable("sessionId") String sessionId, HttpServletRequest request, 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);
}
DeviceUtil.getForObject(device, request,response);
EnvironmentEntity environment = environmentService.getById(session.getEnvId());
if (T.ObjectUtil.isNull(environment)) {
throw new ASWException(RCode.ENVIRONMENT_NOT_EXIST);
}
EnvironmentUtil.getForObject(environment, request, response, sessionId);
}
@GetMapping("/mySession")
public R mySession(@RequestParam Map params){
Page page = environmentService.mySession(params);
return R.ok(page);
}
}

View File

@@ -0,0 +1,17 @@
package net.geedge.asw.module.environment.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import net.geedge.asw.module.environment.entity.EnvironmentEntity;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
import java.util.Map;
@Mapper
public interface EnvironmentDao extends BaseMapper<EnvironmentEntity> {
List<EnvironmentEntity> queryList(Page page, Map<String, Object> params);
List<EnvironmentEntity> mySession(Page page, Map params);
}

View File

@@ -0,0 +1,10 @@
package net.geedge.asw.module.environment.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import net.geedge.asw.module.environment.entity.EnvironmentSessionEntity;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface EnvironmentSessionDao extends BaseMapper<EnvironmentSessionEntity> {
}

View File

@@ -0,0 +1,9 @@
package net.geedge.asw.module.environment.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import net.geedge.asw.module.environment.entity.EnvironmentWorkspaceEntity;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface EnvironmentWorkspaceDao extends BaseMapper<EnvironmentWorkspaceEntity> {
}

View File

@@ -1,4 +1,4 @@
package net.geedge.asw.module.device.entity;
package net.geedge.asw.module.environment.entity;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.annotation.IdType;
@@ -11,8 +11,8 @@ import net.geedge.asw.common.util.T;
import net.geedge.asw.module.sys.entity.SysUserEntity;
@Data
@TableName("device")
public class DeviceEntity {
@TableName("environment")
public class EnvironmentEntity {
@TableId(type = IdType.ASSIGN_UUID)
private String id;
@@ -29,6 +29,7 @@ public class DeviceEntity {
private String createUserId;
private String updateUserId;
@TableField(exist = false)
private String workspaceId;
@TableField(exist = false)

View File

@@ -1,4 +1,4 @@
package net.geedge.asw.module.device.entity;
package net.geedge.asw.module.environment.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
@@ -6,12 +6,12 @@ import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("device_log")
public class DeviceLogEntity {
@TableName("environment_session")
public class EnvironmentSessionEntity {
@TableId(type = IdType.ASSIGN_UUID)
private String id;
private String deviceId;
private String envId;
private String userId;
private Integer status;
private String jobId;

View File

@@ -0,0 +1,19 @@
package net.geedge.asw.module.environment.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("environment_workspace")
public class EnvironmentWorkspaceEntity {
@TableId(type = IdType.ASSIGN_UUID)
private String id;
private String envId;
private String workspaceId;
private Long createTimestamp;
private String createUserId;
}

View File

@@ -0,0 +1,21 @@
package net.geedge.asw.module.environment.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import net.geedge.asw.module.environment.entity.EnvironmentEntity;
import java.util.List;
import java.util.Map;
public interface IEnvironmentService extends IService<EnvironmentEntity>{
EnvironmentEntity queryInfo(String id);
Page queryList(Map<String, Object> params);
EnvironmentEntity saveDevice(EnvironmentEntity entity);
void removeDevice(List<String> ids);
Page mySession(Map params);
}

View File

@@ -0,0 +1,8 @@
package net.geedge.asw.module.environment.service;
import com.baomidou.mybatisplus.extension.service.IService;
import net.geedge.asw.module.environment.entity.EnvironmentSessionEntity;
public interface IEnvironmentSessionService extends IService<EnvironmentSessionEntity>{
}

View File

@@ -0,0 +1,7 @@
package net.geedge.asw.module.environment.service;
import com.baomidou.mybatisplus.extension.service.IService;
import net.geedge.asw.module.environment.entity.EnvironmentWorkspaceEntity;
public interface IEnvironmentWorkspaceService extends IService<EnvironmentWorkspaceEntity> {
}

View File

@@ -0,0 +1,129 @@
package net.geedge.asw.module.environment.service.impl;
import cn.dev33.satoken.stp.StpUtil;
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.RCode;
import net.geedge.asw.common.util.T;
import net.geedge.asw.module.environment.dao.EnvironmentDao;
import net.geedge.asw.module.environment.entity.EnvironmentEntity;
import net.geedge.asw.module.environment.entity.EnvironmentSessionEntity;
import net.geedge.asw.module.environment.entity.EnvironmentWorkspaceEntity;
import net.geedge.asw.module.environment.service.IEnvironmentService;
import net.geedge.asw.module.environment.service.IEnvironmentSessionService;
import net.geedge.asw.module.environment.service.IEnvironmentWorkspaceService;
import net.geedge.asw.module.sys.entity.SysUserEntity;
import net.geedge.asw.module.sys.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Map;
@Service
public class EnvironmentServiceImpl extends ServiceImpl<EnvironmentDao, EnvironmentEntity> implements IEnvironmentService {
private static final Log log = Log.get();
@Autowired
private ISysUserService sysUserService;
@Autowired
private IEnvironmentSessionService deviceSessionService;
@Autowired
private IEnvironmentWorkspaceService deviceWorkspaceService;
@Override
public EnvironmentEntity queryInfo(String id) {
EnvironmentEntity environment = this.getById(id);
T.VerifyUtil.is(environment).notNull(RCode.SYS_RECORD_NOT_FOUND);
// param
environment.setParam(environment.getParamJSONObject());
SysUserEntity createUser = sysUserService.getById(environment.getCreateUserId());
SysUserEntity updateUser = sysUserService.getById(environment.getUpdateUserId());
environment.setCreateUser(createUser);
environment.setUpdateUser(updateUser);
EnvironmentSessionEntity deviceSession = deviceSessionService.getOne(new LambdaQueryWrapper<EnvironmentSessionEntity>().eq(EnvironmentSessionEntity::getEnvId, environment.getId()));
if (null != deviceSession) {
SysUserEntity useUser = sysUserService.getById(deviceSession.getUserId());
JSONObject jsonObject = new JSONObject();
jsonObject.set("id", useUser.getId());
jsonObject.set("name", useUser.getName());
jsonObject.set("startTimestamp", deviceSession.getStartTimestamp());
jsonObject.set("endTimestamp", deviceSession.getEndTimestamp());
environment.setUseUser(jsonObject);
}
return environment;
}
@Override
public Page queryList(Map<String, Object> params) {
Page page = T.PageUtil.getPage(params);
List<EnvironmentEntity> packageList = this.getBaseMapper().queryList(page, params);
for (EnvironmentEntity entity : packageList) {
entity.setParam(entity.getParamJSONObject());
}
page.setRecords(packageList);
return page;
}
@Override
public EnvironmentEntity saveDevice(EnvironmentEntity entity) {
// param
entity.setParam(entity.getParamStr());
// default android
entity.setPlatform(T.StrUtil.emptyToDefault(entity.getPlatform(), "android"));
entity.setCreateTimestamp(System.currentTimeMillis());
entity.setUpdateTimestamp(System.currentTimeMillis());
entity.setCreateUserId(StpUtil.getLoginIdAsString());
entity.setUpdateUserId(StpUtil.getLoginIdAsString());
// save
this.save(entity);
EnvironmentWorkspaceEntity environmentWorkspace = new EnvironmentWorkspaceEntity();
environmentWorkspace.setEnvId(entity.getId());
environmentWorkspace.setWorkspaceId(entity.getWorkspaceId());
environmentWorkspace.setCreateUserId(StpUtil.getLoginIdAsString());
environmentWorkspace.setCreateTimestamp(System.currentTimeMillis());
deviceWorkspaceService.save(environmentWorkspace);
return entity;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void removeDevice(List<String> ids) {
// remove
this.removeBatchByIds(ids);
// session
deviceSessionService.remove(new LambdaQueryWrapper<EnvironmentSessionEntity>().in(EnvironmentSessionEntity::getEnvId, ids));
//device workspace
deviceWorkspaceService.remove(new LambdaQueryWrapper<EnvironmentWorkspaceEntity>().in(EnvironmentWorkspaceEntity::getEnvId, ids));
}
@Override
public Page mySession(Map params) {
String currentUserId = StpUtil.getLoginIdAsString();
params.put("currentUserId", currentUserId);
Page page = new Query(EnvironmentEntity.class).getPage(params);
List<EnvironmentEntity> packageList = this.getBaseMapper().mySession(page, params);
page.setRecords(packageList);
return page;
}
}

View File

@@ -0,0 +1,15 @@
package net.geedge.asw.module.environment.service.impl;
import cn.hutool.log.Log;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import net.geedge.asw.module.environment.dao.EnvironmentSessionDao;
import net.geedge.asw.module.environment.entity.EnvironmentSessionEntity;
import net.geedge.asw.module.environment.service.IEnvironmentSessionService;
import org.springframework.stereotype.Service;
@Service
public class EnvironmentSessionServiceImpl extends ServiceImpl<EnvironmentSessionDao, EnvironmentSessionEntity> implements IEnvironmentSessionService {
private static final Log log = Log.get();
}

View File

@@ -0,0 +1,11 @@
package net.geedge.asw.module.environment.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import net.geedge.asw.module.environment.dao.EnvironmentWorkspaceDao;
import net.geedge.asw.module.environment.entity.EnvironmentWorkspaceEntity;
import net.geedge.asw.module.environment.service.IEnvironmentWorkspaceService;
import org.springframework.stereotype.Service;
@Service
public class EnvironmentWorkspaceServiceImpl extends ServiceImpl<EnvironmentWorkspaceDao, EnvironmentWorkspaceEntity> implements IEnvironmentWorkspaceService {
}

View File

@@ -1,4 +1,4 @@
package net.geedge.asw.module.device.util;
package net.geedge.asw.module.environment.util;
import cn.hutool.core.net.url.UrlBuilder;
import cn.hutool.core.net.url.UrlPath;
@@ -16,7 +16,7 @@ import jakarta.servlet.http.Part;
import net.geedge.asw.common.util.ASWException;
import net.geedge.asw.common.util.Constants;
import net.geedge.asw.common.util.T;
import net.geedge.asw.module.device.entity.DeviceEntity;
import net.geedge.asw.module.environment.entity.EnvironmentEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ByteArrayResource;
@@ -33,22 +33,22 @@ import java.util.*;
@Configuration
@SuppressWarnings("all")
public class DeviceUtil {
public class EnvironmentUtil {
private static Log log = Log.get();
private static RestTemplate restTemplate;
public static void getForObject(DeviceEntity device, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
public static void getForObject(EnvironmentEntity device, HttpServletRequest request, HttpServletResponse response, String sessionId) throws IOException, ServletException {
// path
String pathProfix = T.StrUtil.concat(true, Constants.DEVICE_API_PREFIX, "/", device.getId());
String path = request.getServletPath().replace(pathProfix,"");
String[] paths = request.getServletPath().split(sessionId);
String path = Arrays.asList(paths).getLast();
path = path.startsWith("/") ? (String.format("%s%s", Constants.DEVICE_API_PREFIX, path))
: (String.format("%s/%s", Constants.DEVICE_API_PREFIX, path));
// host port token
JSONObject jsonObject = device.getParamJSONObject();
String host = jsonObject.getStr("host");
String port = jsonObject.getStr("port");
String url = jsonObject.getStr("url");
String token = jsonObject.getStr("token");
// query param
@@ -56,14 +56,11 @@ public class DeviceUtil {
queryString = StrUtil.isNotBlank(queryString) ? queryString : "";
queryString = URLUtil.decode(queryString);
String urlStr = new UrlBuilder(
"http",
host,
Integer.valueOf(port),
UrlPath.of(path, Charset.forName("UTF-8")),
UrlQuery.of(queryString, Charset.forName("UTF-8"), false, true),
null,
StandardCharsets.UTF_8).toString();
String urlStr = UrlBuilder.of(url)
.setPath(UrlPath.of(path, Charset.forName("UTF-8")))
.setQuery(UrlQuery.of(queryString, Charset.forName("UTF-8"), false, true))
.setCharset(StandardCharsets.UTF_8).toString();
// token
HttpHeaders headers = new HttpHeaders();
@@ -147,7 +144,7 @@ public class DeviceUtil {
@Autowired
public void setRestTemplate(RestTemplate restTemplate) {
DeviceUtil.restTemplate = restTemplate;
EnvironmentUtil.restTemplate = restTemplate;
}
}

View File

@@ -1,79 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="net.geedge.asw.module.device.dao.DeviceDao">
<resultMap id="deviceResult" type="net.geedge.asw.module.device.entity.DeviceEntity">
<result property="id" column="id"/>
<result property="name" column="name"/>
<result property="platform" column="platform"/>
<result property="param" column="param"/>
<result property="description" column="description"/>
<result property="status" column="status"/>
<result property="lastHealthCheck" column="last_health_check"/>
<result property="createTimestamp" column="create_timestamp"/>
<result property="updateTimestamp" column="update_timestamp"/>
<result property="createUserId" column="create_user_id"/>
<result property="updateUserId" column="update_user_id"/>
<result property="workspaceId" column="workspace_id"/>
<association property="createUser" columnPrefix="cu_" javaType="net.geedge.asw.module.sys.entity.SysUserEntity">
<id property="id" column="id"/>
<result property="name" column="name"/>
</association>
<association property="updateUser" columnPrefix="uu_" javaType="net.geedge.asw.module.sys.entity.SysUserEntity">
<id property="id" column="id"/>
<result property="name" column="name"/>
</association>
<association property="useUser" columnPrefix="u_" javaType="cn.hutool.json.JSONObject">
<result property="id" column="id"/>
<result property="name" column="name"/>
<result property="startTimestamp" column="start_timestamp"/>
<result property="endTimestamp" column="end_timestamp"/>
</association>
</resultMap>
<select id="queryList" resultMap="deviceResult">
SELECT
d.*,
cu.id AS cu_id,
cu.name AS cu_name,
uu.id AS uu_id,
uu.name AS uu_name,
log.user_id AS u_id,
u.name AS u_name,
log.start_timestamp AS u_start_timestamp,
log.end_timestamp AS u_end_timestamp
FROM device d
LEFT JOIN sys_user cu ON d.create_user_id = cu.id
LEFT JOIN sys_user uu ON d.update_user_id = uu.id
LEFT JOIN device_log log ON d.id = log.device_id
LEFT JOIN sys_user u ON log.user_id = u.id
<where>
<if test="params.ids != null and params.ids != ''">
d.id in
<foreach item="id" collection="params.ids.split(',')" separator="," open="(" close=")">
#{id}
</foreach>
</if>
<if test="params.q != null and params.q != ''">
AND ( locate(#{params.q}, d.name) OR locate(#{params.q}, d.description) )
</if>
<if test="params.workspaceId != null and params.workspaceId != ''">
AND d.workspace_id = #{params.workspaceId}
</if>
</where>
<if test="params.orderBy == null or params.orderBy == ''">
ORDER BY d.create_timestamp
</if>
</select>
</mapper>

View File

@@ -0,0 +1,129 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="net.geedge.asw.module.environment.dao.EnvironmentDao">
<resultMap id="deviceResult" type="net.geedge.asw.module.environment.entity.EnvironmentEntity">
<result property="id" column="id"/>
<result property="name" column="name"/>
<result property="location" column="location"/>
<result property="platform" column="platform"/>
<result property="param" column="param"/>
<result property="description" column="description"/>
<result property="status" column="status"/>
<result property="lastHealthCheck" column="last_health_check"/>
<result property="createTimestamp" column="create_timestamp"/>
<result property="updateTimestamp" column="update_timestamp"/>
<result property="createUserId" column="create_user_id"/>
<result property="updateUserId" column="update_user_id"/>
<association property="createUser" columnPrefix="cu_" javaType="net.geedge.asw.module.sys.entity.SysUserEntity">
<id property="id" column="id"/>
<result property="name" column="name"/>
</association>
<association property="updateUser" columnPrefix="uu_" javaType="net.geedge.asw.module.sys.entity.SysUserEntity">
<id property="id" column="id"/>
<result property="name" column="name"/>
</association>
<association property="useUser" columnPrefix="u_" javaType="cn.hutool.json.JSONObject">
<result property="id" column="id"/>
<result property="name" column="name"/>
<result property="startTimestamp" column="start_timestamp"/>
<result property="endTimestamp" column="end_timestamp"/>
</association>
</resultMap>
<select id="queryList" resultMap="deviceResult">
SELECT
e.*,
cu.id AS cu_id,
cu.name AS cu_name,
uu.id AS uu_id,
uu.name AS uu_name,
es.user_id AS u_id,
u.name AS u_name,
es.start_timestamp AS u_start_timestamp,
es.end_timestamp AS u_end_timestamp
FROM environment e
LEFT JOIN sys_user cu ON e.create_user_id = cu.id
LEFT JOIN sys_user uu ON e.update_user_id = uu.id
LEFT JOIN environment_session es ON e.id = es.env_id
LEFT JOIN environment_workspace ew ON e.id = ew.env_id
LEFT JOIN sys_user u ON es.user_id = u.id
<where>
<if test="params.ids != null and params.ids != ''">
e.id in
<foreach item="id" collection="params.ids.split(',')" separator="," open="(" close=")">
#{id}
</foreach>
</if>
<if test="params.q != null and params.q != ''">
AND ( locate(#{params.q}, e.name) OR locate(#{params.q}, e.description) )
</if>
<if test="params.workspaceId != null and params.workspaceId != ''">
AND ew.workspace_id = #{params.workspaceId}
</if>
</where>
<if test="params.orderBy == null or params.orderBy == ''">
ORDER BY e.create_timestamp
</if>
</select>
<select id="mySession" resultMap="deviceResult">
SELECT
e.*,
cu.id AS cu_id,
cu.name AS cu_name,
uu.id AS uu_id,
uu.name AS uu_name,
es.user_id AS u_id,
u.name AS u_name,
es.start_timestamp AS u_start_timestamp,
es.end_timestamp AS u_end_timestamp
FROM environment e
LEFT JOIN sys_user cu ON e.create_user_id = cu.id
LEFT JOIN sys_user uu ON e.update_user_id = uu.id
LEFT JOIN environment_workspace ew ON e.id = ew.env_id
LEFT JOIN environment_session es ON e.id = es.env_id
LEFT JOIN sys_user u ON es.user_id = u.id
<where>
es.status = 1
<if test="params.ids != null and params.ids != ''">
AND e.id in
<foreach item="id" collection="params.ids.split(',')" separator="," open="(" close=")">
#{id}
</foreach>
</if>
<if test="params.q != null and params.q != ''">
AND ( locate(#{params.q}, e.name) OR locate(#{params.q}, e.description) )
</if>
<if test="params.workspaceId != null and params.workspaceId != ''">
AND ew.workspace_id = #{params.workspaceId}
</if>
<if test="params.currentUserId != null and params.currentUserId != ''">
AND es.user_id = #{params.currentUserId}
</if>
</where>
<if test="params.orderBy == null or params.orderBy == ''">
ORDER BY e.create_timestamp
</if>
</select>
</mapper>

View File

@@ -121,5 +121,9 @@ INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (199, '100017', 'SYS_ROLE_BUILT_IN', '内置权限不能删除或修改', 'zh', '', 'admin', 1724030366000);
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (201, '100018', 'SYS_ROLE_NOT_DELETE', 'Used role cannot be delete', 'en', '', 'admin', 1724030366000);
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (203, '100018', 'SYS_ROLE_NOT_DELETE', '已使用权限不能删除', 'zh', '', 'admin', 1724030366000);
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (205, '601001', 'ENVIRONMENT_SESSION_NOT_EXIST', 'environment session does not exist', 'en', '', 'admin', 1724030366000);
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (207, '601001', 'ENVIRONMENT_SESSION_NOT_EXIST', '会话不存在', 'zh', '', 'admin', 1724030366000);
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (209, '601002', 'ENVIRONMENT_NOT_EXIST', 'environment does not exist', 'en', '', 'admin', 1724030366000);
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (211, '601002', 'ENVIRONMENT_NOT_EXIST', '环境不存在', 'zh', '', 'admin', 1724030366000);
SET FOREIGN_KEY_CHECKS = 1;

View File

@@ -462,10 +462,10 @@ INSERT INTO `workspace_member` (`workspace_id`, `user_id`, `role_id`, `create_ti
/**
* 新增 device
* 新增 environment
*/
DROP TABLE IF EXISTS `device`;
CREATE TABLE `device` (
DROP TABLE IF EXISTS `environment`;
CREATE TABLE `environment` (
`id` varchar(64) NOT NULL COMMENT '主键',
`name` varchar(256) NOT NULL DEFAULT '' COMMENT '名称',
`location` varchar(256) NOT NULL DEFAULT '' COMMENT '位置',
@@ -478,24 +478,37 @@ CREATE TABLE `device` (
`update_timestamp` bigint(20) NOT NULL COMMENT '更新时间戳',
`create_user_id` varchar(64) NOT NULL COMMENT '创建人',
`update_user_id` varchar(64) NOT NULL COMMENT '更新人',
`workspace_id` varchar(64) NOT NULL DEFAULT '' COMMENT '工作空间ID',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_name` (`name`) USING BTREE,
KEY `idx_status` (`status`) USING BTREE,
KEY `idx_status` (`status`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/**
* 新增 environment_workspace 表
*/
DROP TABLE IF EXISTS `environment_workspace`;
CREATE TABLE `environment_workspace` (
`id` varchar(64) NOT NULL COMMENT '主键',
`env_id` varchar(64) NOT NULL DEFAULT '' COMMENT '名称',
`workspace_id` varchar(64) NOT NULL DEFAULT '' COMMENT '位置',
`create_timestamp` bigint(20) NOT NULL COMMENT '创建时间戳',
`create_user_id` varchar(64) NOT NULL COMMENT '创建人',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_workspace_id` (`workspace_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/**
* 新增 device_log
* 新增 environment_session
*/
DROP TABLE IF EXISTS `device_log`;
CREATE TABLE `device_log` (
DROP TABLE IF EXISTS `environment_session`;
CREATE TABLE `environment_session` (
`id` varchar(64) NOT NULL COMMENT '主键',
`device_id` varchar(64) NOT NULL DEFAULT '' COMMENT '设备id',
`env_id` varchar(64) NOT NULL DEFAULT '' COMMENT '设备id',
`user_id` varchar(64) NOT NULL DEFAULT '' COMMENT '用户id',
`start_timestamp` bigint(20) NOT NULL COMMENT '开始时间',
`end_timestamp` bigint(20) NOT NULL COMMENT '结束时间',
`end_timestamp` bigint(20) NOT NULL DEFAULT -1 COMMENT '结束时间',
`status` int(1) NOT NULL DEFAULT 1 COMMENT '状态,1使用中;2已结束',
`job_id` varchar(64) NOT NULL DEFAULT '' COMMENT '任务id',
`workspace_id` varchar(64) NOT NULL DEFAULT '' COMMENT '工作空间ID',