fix:引擎申请设备超时后因根据设备id释放设备引起正在执行任务的设备失去使用权。

修改方案:
1.请求方申请设备时自带token值,设备管理服务判断设备是否空闲,如果空闲,那么请求方提供的token作为本次申请的token;
2.如果在申请过程中出现问题,请求方依然可以根据token释放设备,设备管理服务接收到改token的释放也会检查token是否有效

设备管理
1.增加接口:批量申请设备使用时,使用请求方提供的token

执行引擎
1.更改设备申请接口
2.修改移动和PC的设备申请逻辑,将两者相同逻辑部分进行抽取,简化代码
3.配置文件增加配置,亦可以不修改,接口地址有默认值。
hz_1122_temp
李杰应 2024-11-27 03:54:06 +08:00
parent e6b4fe6d88
commit 5a5bef44c2
23 changed files with 281 additions and 129 deletions

View File

@ -143,4 +143,10 @@ public class AtuServerConfig {
private String remoteProtocol; private String remoteProtocol;
private Boolean IsPcExecutor; private Boolean IsPcExecutor;
private String acquireDeviceWithTokenUrl;
public String getAcquireDeviceWithTokenUrl() {
return StringUtils.isBlank(this.acquireDeviceWithTokenUrl) ? "/api/cctp-device-mgr/pub/deviceList/apply/batchWithToken" : this.acquireDeviceWithTokenUrl;
}
} }

View File

@ -0,0 +1,21 @@
package net.northking.cctp.se.device.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.ToString;
@Data
@ApiModel(value = "设备申请")
@ToString
public class ApplyDeviceDto {
@ApiModelProperty(value = "设备Id")
private String id;
@ApiModelProperty(value = "设备类型", notes = "1-pc2-移动")
private String type;
@ApiModelProperty(value = "token", notes = "可由请求方带上")
private String token;
}

View File

@ -0,0 +1,25 @@
package net.northking.cctp.se.device.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.ToString;
import java.util.List;
@Data
@ApiModel(value = "设备批量申请dto")
@ToString
public class BatchApplyDeviceDto {
@ApiModelProperty(value = "申请人id")
private String id;
@ApiModelProperty(value = "使用来源engine为引擎使用0")
private String userBy;
@ApiModelProperty(value = "设备列表")
private List<ApplyDeviceDto> deviceList;
}

View File

@ -8,6 +8,8 @@ import com.rabbitmq.client.GetResponse;
import net.northking.cctp.common.http.ResultWrapper; import net.northking.cctp.common.http.ResultWrapper;
import net.northking.cctp.element.core.exception.ExecuteException; import net.northking.cctp.element.core.exception.ExecuteException;
import net.northking.cctp.se.config.AtuServerConfig; import net.northking.cctp.se.config.AtuServerConfig;
import net.northking.cctp.se.device.dto.ApplyDeviceDto;
import net.northking.cctp.se.device.dto.BatchApplyDeviceDto;
import net.northking.cctp.se.dto.ScriptEngineInfo; import net.northking.cctp.se.dto.ScriptEngineInfo;
import net.northking.cctp.se.exec.constant.AtuExecConstant; import net.northking.cctp.se.exec.constant.AtuExecConstant;
import net.northking.cctp.se.lifecycle.EngineRuntime; import net.northking.cctp.se.lifecycle.EngineRuntime;
@ -24,11 +26,12 @@ import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitAdmin; import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.ResponseEntity; import org.springframework.http.*;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import java.util.*; import java.util.*;
@ -98,42 +101,10 @@ public class AtuPlanTaskSchedule {
//获取引擎注册后的设备id //获取引擎注册后的设备id
EngineRuntime engineRuntime = EngineRuntime.getRuntime(); EngineRuntime engineRuntime = EngineRuntime.getRuntime();
ScriptEngineInfo info = engineRuntime.getEngineInfo(); ScriptEngineInfo info = engineRuntime.getEngineInfo();
Map<String,Object> paramMap = new HashMap<>(); List<String> deviceList = Collections.singletonList(taskDeviceId); // 需要申请的设备集合
paramMap.put("id",info.getEngineId());
List<String> tryAcqurieDeviceIdList = Collections.singletonList(taskDeviceId);
paramMap.put("deviceList",tryAcqurieDeviceIdList);
paramMap.put("type","1");
paramMap.put("userBy","engine");
String url = atuServerConfig.getServerUrl() + atuServerConfig.getTryAcqurieDeviceUrl();
try {
ResponseEntity<ResultWrapper> result = restTemplate.postForEntity(url, paramMap, ResultWrapper.class);
if(HttpStatus.OK.equals(result.getStatusCode())){
ResultWrapper deviceResult = result.getBody();
if (deviceResult != null && deviceResult.isSuccess()) {
List<Map<String,String>> body = (List<Map<String,String>>)deviceResult.getData();
if(!CollectionUtils.isEmpty(body)){
logger.debug("移动任务请求占用成功移动端设备信息:"+JSON.toJSONString(body));
for (int i = 0; i < body.size(); i++) {
Map<String, String> deviceMap = body.get(i);
String deviceId = deviceMap.get("id");
String deviceToken = deviceMap.get("token");
//获取设备对应的一条计划信息
boolean isUsed = getTaskFromQueue(deviceId, deviceToken,TYPE_MOBILE);
if(!isUsed){
//无任务 释放设备
logger.debug("无任务释放移动端设备:"+deviceId);
releaseDevice(deviceToken);
}
}
}
}
} List<ApplyDeviceDto> resultList = acquireDevice(deviceList, TYPE_MOBILE, info.getEngineId());
}catch (Exception e){ useDeviceGetTask(resultList, TYPE_MOBILE);
logger.error("请求占用设备失败,原因:",e);
//释放所有设备
releaseDevices(e, info.getEngineId(), tryAcqurieDeviceIdList);
}
} }
} }
} }
@ -152,74 +123,88 @@ public class AtuPlanTaskSchedule {
if(!CollectionUtils.isEmpty(batchList)){ if(!CollectionUtils.isEmpty(batchList)){
logger.debug("存在PC类型的委托任务共{}条", batchList.size()); logger.debug("存在PC类型的委托任务共{}条", batchList.size());
if(batchList.size()>0){ if(batchList.size()>0){
Map<String,Object> paramMap = new HashMap<>();
List<String> list = new ArrayList<>(); List<String> list = new ArrayList<>();
list.add(deviceId); list.add(deviceId);
paramMap.put("id",engineId);
paramMap.put("deviceList",list); List<ApplyDeviceDto> resultList = acquireDevice(list, TYPE_PC, engineId);
paramMap.put("type","2"); useDeviceGetTask(resultList, TYPE_PC);
paramMap.put("userBy","engine"); }
//判断设备是否空闲 }
String url = atuServerConfig.getServerUrl() + atuServerConfig.getTryAcqurieDeviceUrl(); }
private void useDeviceGetTask(List<ApplyDeviceDto> deviceList, String type) {
if (!deviceList.isEmpty()) {
for (ApplyDeviceDto device : deviceList) {
boolean isUsed = false;
try { try {
ResponseEntity<ResultWrapper> resultEntity = restTemplate.postForEntity(url, paramMap, ResultWrapper.class); logger.debug("设备{}占用成功token{}", device.getId(), device.getToken());
logger.debug("pc任务请求设备使用结果"+ JSON.toJSONString(resultEntity)); isUsed = getTaskFromQueue(device.getId(), device.getToken(), type);
if (HttpStatus.OK.equals(resultEntity.getStatusCode())) {
ResultWrapper deviceResult = resultEntity.getBody();
if (deviceResult!= null && deviceResult.isSuccess()) {
List<Map<String, String>> body = (List<Map<String, String>>) deviceResult.getData();
if (!CollectionUtils.isEmpty(body)) {
Map<String, String> deviceMap = body.get(0);
String deviceToken = deviceMap.get("token");
logger.debug("设备token" + deviceToken);
logger.debug("当前设备{}占用成功。", deviceId);
boolean isUsed = getTaskFromQueue(deviceId, deviceToken, TYPE_PC);
if (!isUsed) { if (!isUsed) {
//设备无任务可领 // 设备无任务可领
logger.debug("无任务释放PC设备" + deviceId); logger.debug("无任务释放设备:{}", device.getId());
releaseDevice(deviceToken);
}
}
}
} }
} catch (Exception e) { } catch (Exception e) {
logger.error("设备请求占用异常:",e); logger.error("从队列获取任务失败,准备释放设备{}", device.getId(), e);
releaseDevices(e, info.getEngineId(), list); } finally {
if (!isUsed) {
releaseDevice(device.getToken());
}
} }
} }
} }
} }
private void releaseDevices(Exception e, String engineId, List<String> deviceIds) {
//释放所有设备 /**
String errorMsg = e.getMessage(); *
if (errorMsg.contains("Read timed out")) { * @param deviceList
int count = 0; * @param type 1-pc 2-
Map<String, Object> requestMap = new HashMap<>(); * @param engineId id
requestMap.put("id", engineId); * @return
requestMap.put("deviceList", deviceIds); */
while (count++ < 50) { private List<ApplyDeviceDto> acquireDevice(List<String> deviceList, String type, String engineId) {
if (deviceList.isEmpty()) {
return new ArrayList<>();
}
BatchApplyDeviceDto queryDto = new BatchApplyDeviceDto();
queryDto.setId(engineId);
queryDto.setUserBy("engine");
List<ApplyDeviceDto> queryDeviceList = new ArrayList<>();
queryDto.setDeviceList(queryDeviceList);
for (String deviceId : deviceList) {
ApplyDeviceDto dto = new ApplyDeviceDto();
dto.setId(deviceId);
dto.setType(type);
dto.setToken(DigestUtils.md5DigestAsHex(String.format("%s@%s@%s", deviceId, engineId, System.currentTimeMillis()).getBytes()));
queryDeviceList.add(dto);
}
try { try {
logger.debug("pc任务请求占用设备超时处理===="); String url = atuServerConfig.getServerUrl() + atuServerConfig.getAcquireDeviceWithTokenUrl();
//请求超时释放请求设备 HttpHeaders headers = new HttpHeaders();
String urlRelease = atuServerConfig.getServerUrl() + atuServerConfig.getReleaseDeviceBatch(); headers.setContentType(MediaType.APPLICATION_JSON);
ResponseEntity<ResultWrapper> entity = restTemplate.postForEntity(urlRelease, requestMap, ResultWrapper.class); HttpEntity<BatchApplyDeviceDto> requestEntity = new HttpEntity<>(queryDto, headers);
if (HttpStatus.OK == entity.getStatusCode()) { ResponseEntity<ResultWrapper<List<ApplyDeviceDto>>> resultEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, new ParameterizedTypeReference<ResultWrapper<List<ApplyDeviceDto>>>(){});
count += 50; logger.debug("{} 任务请求设备使用是结果:{}", TYPE_MOBILE.equals(type) ? "移动" : "PC", JSON.toJSONString(resultEntity));
} if (resultEntity.getStatusCode().is2xxSuccessful()) {
Thread.sleep(2000); ResultWrapper<List<ApplyDeviceDto>> deviceResult = resultEntity.getBody();
} catch (Exception innerE) { if (deviceResult != null && deviceResult.isSuccess() && deviceResult.getData() != null && !deviceResult.getData().isEmpty()) {
// todo: 增加发送队列 return deviceResult.getData();
logger.error("超时释放设备失败:", innerE);
logger.debug("使用队列方式释放使用的设备:{}", requestMap);
try {
rabbitTemplate.convertAndSend(AtuExecConstant.ENGINE_RELEASE_ID, new Message(om.writeValueAsBytes(requestMap)));
count += 50;
} catch (JsonProcessingException jpe) {
logger.error("释放设备失败", jpe);
} }
} }
} catch (Exception e) {
logger.error("设备请求占用异常", e);
releaseDeviceAsException(queryDeviceList);
} }
return new ArrayList<>();
}
/**
* token使tokentoken
* @param queryDeviceList
*/
private void releaseDeviceAsException(List<ApplyDeviceDto> queryDeviceList) {
for (ApplyDeviceDto dto : queryDeviceList) {
releaseDevice(dto.getToken());
} }
} }

View File

@ -44,6 +44,7 @@ atu:
projectInfo: /api/cctp-projects/pub/project/query/info?projectId={projectId} projectInfo: /api/cctp-projects/pub/project/query/info?projectId={projectId}
testSysUrl: /api/cctp-projects/pub/CpProjectEnvSyss/querySysUrl testSysUrl: /api/cctp-projects/pub/CpProjectEnvSyss/querySysUrl
busComInfoUrl: /api/atu-script-case/pub/busCom/findBusComName busComInfoUrl: /api/atu-script-case/pub/busCom/findBusComName
acquireDeviceWithTokenUrl: /api/cctp-device-mgr/pub/deviceList/apply/batchWithToken
engine: engine:
executor-pool: executor-pool:
pcSize: 1 pcSize: 1

View File

@ -44,6 +44,7 @@ atu:
projectInfo: /api/cctp-projects/pub/project/query/info?projectId={projectId} projectInfo: /api/cctp-projects/pub/project/query/info?projectId={projectId}
testSysUrl: /api/cctp-projects/pub/CpProjectEnvSyss/querySysUrl testSysUrl: /api/cctp-projects/pub/CpProjectEnvSyss/querySysUrl
busComInfoUrl: /api/atu-script-case/pub/busCom/findBusComName busComInfoUrl: /api/atu-script-case/pub/busCom/findBusComName
acquireDeviceWithTokenUrl: /api/cctp-device-mgr/pub/deviceList/apply/batchWithToken
engine: engine:
executor-pool: executor-pool:
pcSize: 1 pcSize: 1

View File

@ -45,6 +45,7 @@ atu:
projectInfo: /api/cctp-projects/pub/project/query/info?projectId={projectId} projectInfo: /api/cctp-projects/pub/project/query/info?projectId={projectId}
testSysUrl: /api/cctp-projects/pub/CpProjectEnvSyss/querySysUrl testSysUrl: /api/cctp-projects/pub/CpProjectEnvSyss/querySysUrl
busComInfoUrl: /api/atu-script-case/pub/busCom/findBusComName busComInfoUrl: /api/atu-script-case/pub/busCom/findBusComName
acquireDeviceWithTokenUrl: /api/cctp-device-mgr/pub/deviceList/apply/batchWithToken
engine: engine:
executor-pool: executor-pool:
pcSize: 1 pcSize: 1

View File

@ -44,6 +44,7 @@ atu:
projectInfo: /api/cctp-projects/pub/project/query/info?projectId={projectId} projectInfo: /api/cctp-projects/pub/project/query/info?projectId={projectId}
testSysUrl: /api/cctp-projects/pub/CpProjectEnvSyss/querySysUrl testSysUrl: /api/cctp-projects/pub/CpProjectEnvSyss/querySysUrl
busComInfoUrl: /api/atu-script-case/pub/busCom/findBusComName busComInfoUrl: /api/atu-script-case/pub/busCom/findBusComName
acquireDeviceWithTokenUrl: /api/cctp-device-mgr/pub/deviceList/apply/batchWithToken
engine: engine:
executor-pool: executor-pool:
pcSize: 1 pcSize: 1

View File

@ -44,6 +44,7 @@ atu:
projectInfo: /api/cctp-projects/pub/project/query/info?projectId={projectId} projectInfo: /api/cctp-projects/pub/project/query/info?projectId={projectId}
testSysUrl: /api/cctp-projects/pub/CpProjectEnvSyss/querySysUrl testSysUrl: /api/cctp-projects/pub/CpProjectEnvSyss/querySysUrl
busComInfoUrl: /api/atu-script-case/pub/busCom/findBusComName busComInfoUrl: /api/atu-script-case/pub/busCom/findBusComName
acquireDeviceWithTokenUrl: /api/cctp-device-mgr/pub/deviceList/apply/batchWithToken
engine: engine:
executor-pool: executor-pool:
pcSize: 1 pcSize: 1

View File

@ -45,6 +45,7 @@ atu:
projectInfo: /api/cctp-projects/pub/project/query/info?projectId={projectId} projectInfo: /api/cctp-projects/pub/project/query/info?projectId={projectId}
testSysUrl: /api/cctp-projects/pub/CpProjectEnvSyss/querySysUrl testSysUrl: /api/cctp-projects/pub/CpProjectEnvSyss/querySysUrl
busComInfoUrl: /api/atu-script-case/pub/busCom/findBusComName busComInfoUrl: /api/atu-script-case/pub/busCom/findBusComName
acquireDeviceWithTokenUrl: /api/cctp-device-mgr/pub/deviceList/apply/batchWithToken
engine: engine:
executor-pool: executor-pool:
pcSize: 1 pcSize: 1

View File

@ -46,6 +46,7 @@ atu:
projectInfo: /api/cctp-projects/pub/project/query/info?projectId={projectId} projectInfo: /api/cctp-projects/pub/project/query/info?projectId={projectId}
testSysUrl: /api/cctp-projects/pub/CpProjectEnvSyss/querySysUrl testSysUrl: /api/cctp-projects/pub/CpProjectEnvSyss/querySysUrl
busComInfoUrl: /api/atu-script-case/pub/busCom/findBusComName busComInfoUrl: /api/atu-script-case/pub/busCom/findBusComName
acquireDeviceWithTokenUrl: /api/cctp-device-mgr/pub/deviceList/apply/batchWithToken
engine: engine:
executor-pool: executor-pool:
pcSize: 1 pcSize: 1

View File

@ -44,6 +44,7 @@ atu:
projectInfo: /api/cctp-projects/pub/project/query/info?projectId={projectId} projectInfo: /api/cctp-projects/pub/project/query/info?projectId={projectId}
testSysUrl: /api/cctp-projects/pub/CpProjectEnvSyss/querySysUrl testSysUrl: /api/cctp-projects/pub/CpProjectEnvSyss/querySysUrl
busComInfoUrl: /api/atu-script-case/pub/busCom/findBusComName busComInfoUrl: /api/atu-script-case/pub/busCom/findBusComName
acquireDeviceWithTokenUrl: /api/cctp-device-mgr/pub/deviceList/apply/batchWithToken
engine: engine:
executor-pool: executor-pool:
pcSize: 1 pcSize: 1

View File

@ -44,6 +44,7 @@ atu:
projectInfo: /api/cctp-projects/pub/project/query/info?projectId={projectId} projectInfo: /api/cctp-projects/pub/project/query/info?projectId={projectId}
testSysUrl: /api/cctp-projects/pub/CpProjectEnvSyss/querySysUrl testSysUrl: /api/cctp-projects/pub/CpProjectEnvSyss/querySysUrl
busComInfoUrl: /api/atu-script-case/pub/busCom/findBusComName busComInfoUrl: /api/atu-script-case/pub/busCom/findBusComName
acquireDeviceWithTokenUrl: /api/cctp-device-mgr/pub/deviceList/apply/batchWithToken
engine: engine:
executor-pool: executor-pool:
pcSize: 1 pcSize: 1

View File

@ -46,6 +46,7 @@ atu:
projectInfo: /api/cctp-projects/pub/project/query/info?projectId={projectId} projectInfo: /api/cctp-projects/pub/project/query/info?projectId={projectId}
testSysUrl: /api/cctp-projects/pub/CpProjectEnvSyss/querySysUrl testSysUrl: /api/cctp-projects/pub/CpProjectEnvSyss/querySysUrl
busComInfoUrl: /api/atu-script-case/pub/busCom/findBusComName busComInfoUrl: /api/atu-script-case/pub/busCom/findBusComName
acquireDeviceWithTokenUrl: /api/cctp-device-mgr/pub/deviceList/apply/batchWithToken
engine: engine:
executor-pool: executor-pool:
pcSize: 1 pcSize: 1

View File

@ -46,6 +46,7 @@ atu:
projectInfo: /api/cctp-projects/pub/project/query/info?projectId={projectId} projectInfo: /api/cctp-projects/pub/project/query/info?projectId={projectId}
testSysUrl: /api/cctp-projects/pub/CpProjectEnvSyss/querySysUrl testSysUrl: /api/cctp-projects/pub/CpProjectEnvSyss/querySysUrl
busComInfoUrl: /api/atu-script-case/pub/busCom/findBusComName busComInfoUrl: /api/atu-script-case/pub/busCom/findBusComName
acquireDeviceWithTokenUrl: /api/cctp-device-mgr/pub/deviceList/apply/batchWithToken
engine: engine:
executor-pool: executor-pool:
pcSize: 1 pcSize: 1

View File

@ -44,6 +44,7 @@ atu:
projectInfo: /api/cctp-projects/pub/project/query/info?projectId={projectId} projectInfo: /api/cctp-projects/pub/project/query/info?projectId={projectId}
testSysUrl: /api/cctp-projects/pub/CpProjectEnvSyss/querySysUrl testSysUrl: /api/cctp-projects/pub/CpProjectEnvSyss/querySysUrl
busComInfoUrl: /api/atu-script-case/pub/busCom/findBusComName busComInfoUrl: /api/atu-script-case/pub/busCom/findBusComName
acquireDeviceWithTokenUrl: /api/cctp-device-mgr/pub/deviceList/apply/batchWithToken
engine: engine:
executor-pool: executor-pool:
pcSize: 1 pcSize: 1

View File

@ -4,10 +4,7 @@ import net.northking.cctp.common.db.Pagination;
import net.northking.cctp.common.http.QueryByPage; import net.northking.cctp.common.http.QueryByPage;
import net.northking.cctp.device.db.entity.CdDeviceToken; import net.northking.cctp.device.db.entity.CdDeviceToken;
import net.northking.cctp.device.db.entity.CdDeviceUsageLog; import net.northking.cctp.device.db.entity.CdDeviceUsageLog;
import net.northking.cctp.device.dto.device.CdMobileDeviceExitDto; import net.northking.cctp.device.dto.device.*;
import net.northking.cctp.device.dto.device.DeviceLockDto;
import net.northking.cctp.device.dto.device.DeviceLogDto;
import net.northking.cctp.device.dto.device.DeviceInfoDto;
import net.northking.cctp.device.dto.pcDevice.CdDeviceRemoteDto; import net.northking.cctp.device.dto.pcDevice.CdDeviceRemoteDto;
import net.northking.cctp.device.dto.pcDevice.CdPcDeviceExitDto; import net.northking.cctp.device.dto.pcDevice.CdPcDeviceExitDto;
import net.northking.cctp.device.dto.pcDevice.CdPcDeviceRemoteDto; import net.northking.cctp.device.dto.pcDevice.CdPcDeviceRemoteDto;
@ -62,4 +59,13 @@ public interface DeviceActivityApiService {
* @param deviceTokens token * @param deviceTokens token
*/ */
void release(List<CdDeviceToken> deviceTokens); void release(List<CdDeviceToken> deviceTokens);
/**
*
* @param devices
* @param request
* @return
*/
List<ApplyDeviceDto> deviceListApply(BatchApplyDeviceDto devices, HttpServletRequest request);
} }

View File

@ -3,7 +3,6 @@ package net.northking.cctp.device.api.activity.service;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.TypeReference;
import com.github.pagehelper.page.PageMethod;
import net.northking.cctp.common.cache.EntityNameCache; import net.northking.cctp.common.cache.EntityNameCache;
import net.northking.cctp.common.cache.EntityNameCatalog; import net.northking.cctp.common.cache.EntityNameCatalog;
import net.northking.cctp.common.db.Pagination; import net.northking.cctp.common.db.Pagination;
@ -15,10 +14,7 @@ import net.northking.cctp.device.constants.DeviceConstants;
import net.northking.cctp.device.constants.DeviceError; import net.northking.cctp.device.constants.DeviceError;
import net.northking.cctp.device.db.entity.*; import net.northking.cctp.device.db.entity.*;
import net.northking.cctp.device.db.service.*; import net.northking.cctp.device.db.service.*;
import net.northking.cctp.device.dto.device.CdMobileDeviceExitDto; import net.northking.cctp.device.dto.device.*;
import net.northking.cctp.device.dto.device.DeviceInfoDto;
import net.northking.cctp.device.dto.device.DeviceLockDto;
import net.northking.cctp.device.dto.device.DeviceLogDto;
import net.northking.cctp.device.dto.pcDevice.CdDeviceRemoteDto; import net.northking.cctp.device.dto.pcDevice.CdDeviceRemoteDto;
import net.northking.cctp.device.dto.pcDevice.CdPcDeviceExitDto; import net.northking.cctp.device.dto.pcDevice.CdPcDeviceExitDto;
import net.northking.cctp.device.dto.pcDevice.CdPcDeviceRemoteDto; import net.northking.cctp.device.dto.pcDevice.CdPcDeviceRemoteDto;
@ -31,6 +27,7 @@ import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.integration.redis.util.RedisLockRegistry; import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils; import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@ -38,7 +35,6 @@ import javax.servlet.http.HttpServletRequest;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
import java.util.stream.Collectors;
@Service @Service
@ -690,6 +686,10 @@ public class DeviceActivityApiServiceImpl implements DeviceActivityApiService {
} }
public Map<String, String> applyMobDevice(String deviceId, String userId,HttpServletRequest request,String userBy) { public Map<String, String> applyMobDevice(String deviceId, String userId,HttpServletRequest request,String userBy) {
return applyMobDevice(deviceId, userId, request, userBy, null);
}
public Map<String, String> applyMobDevice(String deviceId, String userId,HttpServletRequest request,String userBy, String token) {
//校验设备是否使用中 如果设备使用中 直接返回null //校验设备是否使用中 如果设备使用中 直接返回null
CdDeviceStatus status = this.cdDeviceStatusService.findByPrimaryKey(deviceId); CdDeviceStatus status = this.cdDeviceStatusService.findByPrimaryKey(deviceId);
if (!status.getUsageStatus().equals(DeviceConstants.DEVICE_STATUS_ONLINE)) { if (!status.getUsageStatus().equals(DeviceConstants.DEVICE_STATUS_ONLINE)) {
@ -705,8 +705,10 @@ public class DeviceActivityApiServiceImpl implements DeviceActivityApiService {
CdDeviceCtrl ctrl = this.cdDeviceCtrlService.findByPrimaryKey(device.getCtrlId()); CdDeviceCtrl ctrl = this.cdDeviceCtrlService.findByPrimaryKey(device.getCtrlId());
Date date = new Date(); Date date = new Date();
if (StringUtils.hasText(token)) { // 如果传入token那么使用传入token
String index = deviceId + DeviceConstants.STR_REGEX + ctrl.getId() + DeviceConstants.STR_REGEX + date; String index = deviceId + DeviceConstants.STR_REGEX + ctrl.getId() + DeviceConstants.STR_REGEX + date;
String token = DigestUtils.md5DigestAsHex(index.getBytes()); token = DigestUtils.md5DigestAsHex(index.getBytes());
}
//记录到设备令牌表 //记录到设备令牌表
CdDeviceToken cdDeviceToken = new CdDeviceToken(); CdDeviceToken cdDeviceToken = new CdDeviceToken();
@ -748,6 +750,10 @@ public class DeviceActivityApiServiceImpl implements DeviceActivityApiService {
} }
public Map<String, String> applyPcDevice(String deviceId, String userId,HttpServletRequest request,String userBy) { public Map<String, String> applyPcDevice(String deviceId, String userId,HttpServletRequest request,String userBy) {
return applyPcDevice(deviceId, userId, request, userBy, null);
}
public Map<String, String> applyPcDevice(String deviceId, String userId,HttpServletRequest request,String userBy, String token) {
CdDeviceStatus status = this.cdDeviceStatusService.findByPrimaryKey(deviceId); CdDeviceStatus status = this.cdDeviceStatusService.findByPrimaryKey(deviceId);
if (!status.getUsageStatus().equals(DeviceConstants.DEVICE_STATUS_ONLINE)) { if (!status.getUsageStatus().equals(DeviceConstants.DEVICE_STATUS_ONLINE)) {
return null; return null;
@ -760,8 +766,10 @@ public class DeviceActivityApiServiceImpl implements DeviceActivityApiService {
List<CdEngineInfo> engineList = this.cdEngineInfoService.query(cdEngineInfo); List<CdEngineInfo> engineList = this.cdEngineInfoService.query(cdEngineInfo);
//新增令牌 //新增令牌
Date date = new Date(); Date date = new Date();
if (StringUtils.hasText(token)) {
String index = deviceId + DeviceConstants.STR_REGEX + engineList.get(0).getId() + DeviceConstants.STR_REGEX + date; String index = deviceId + DeviceConstants.STR_REGEX + engineList.get(0).getId() + DeviceConstants.STR_REGEX + date;
String token = DigestUtils.md5DigestAsHex(index.getBytes()); token = DigestUtils.md5DigestAsHex(index.getBytes());
}
//记录到设备令牌表 //记录到设备令牌表
CdDeviceToken cdDeviceToken = new CdDeviceToken(); CdDeviceToken cdDeviceToken = new CdDeviceToken();
cdDeviceToken.setId(deviceId); cdDeviceToken.setId(deviceId);
@ -837,4 +845,52 @@ public class DeviceActivityApiServiceImpl implements DeviceActivityApiService {
} }
} }
} }
/**
*
* type1pc2
*
* @param devices
* @param request
* @return
*/
@Override
public List<ApplyDeviceDto> deviceListApply(BatchApplyDeviceDto devices, HttpServletRequest request) {
List<ApplyDeviceDto> resultList = new ArrayList<>();
String userId = devices.getId();
String userBy = devices.getUserBy();
if (!CollectionUtils.isEmpty(devices.getDeviceList())) {
List<ApplyDeviceDto> applyList = devices.getDeviceList();
for (ApplyDeviceDto device : applyList) {
ApplyDeviceDto result = new ApplyDeviceDto();
Map<String, String> deviceTokenMap = null;
String deviceId = device.getId();
String lockKey = String.format("%s%s", DeviceConstants.ENGINE_DEVICE_TYPE_MOBILE.equals(device.getType()) ? DeviceConstants.LOCK_MOBILE : DeviceConstants.LOCK_PC, deviceId);
Lock lock = redisLockRegistry.obtain(lockKey);
try {
if (lock.tryLock(5000, TimeUnit.MILLISECONDS)) {
if (DeviceConstants.ENGINE_DEVICE_TYPE_MOBILE.equals(device.getType())) {
deviceTokenMap = applyMobDevice(deviceId, userId, request, userBy, device.getToken());
} else {
deviceTokenMap = applyPcDevice(deviceId, userId, request, userBy, device.getToken());
}
}
} catch (InterruptedException e) {
logger.error("申请移动设备异常:",e);
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
if (deviceTokenMap != null) {
result.setId(deviceTokenMap.get("id"));
result.setToken(deviceTokenMap.get("token"));
if (StringUtils.hasText(result.getToken())) {
resultList.add(result);
}
}
}
}
return resultList;
}
} }

View File

@ -38,7 +38,7 @@ public class DeviceMQReceiver {
private final static Logger logger = LoggerFactory.getLogger(DeviceMQReceiver.class); private final static Logger logger = LoggerFactory.getLogger(DeviceMQReceiver.class);
@RabbitListener(queuesToDeclare = {@Queue(value = "execute.engine.release")}) @RabbitListener(queuesToDeclare = {@Queue(value = "execute.engine.release")})
public void DeviceMQReceiver(Message message){ public void releaseReceive(Message message){
// 释放设备 // 释放设备
try{ try{
byte[] body = message.getBody(); byte[] body = message.getBody();
@ -73,21 +73,4 @@ public class DeviceMQReceiver {
logger.error("释放设备异常",e); logger.error("释放设备异常",e);
} }
} }
/**
*
* @param message
*/
@RabbitListener(queuesToDeclare = {@Queue(value = "execute.engine.release.id")})
public void releaseById(Message message){
try{
byte[] body = message.getBody();
Map<String, Object> mqParam = om.readValue(body, new TypeReference<Map<String, Object>>() {
});
activityService.releaseDeviceList(mqParam);
}catch (Exception e){
logger.error("释放设备异常",e);
}
}
} }

View File

@ -20,7 +20,7 @@ public class DeviceConstants {
*/ */
public final static String LOCK_MOBILE = "lock:mobile:"; public final static String LOCK_MOBILE = "lock:mobile:";
public final static String LOCK_PC = "lock:mobile:"; public final static String LOCK_PC = "lock:pc:";
//安卓类型 //安卓类型
public final static String MOBILE_PLATFORM_ANDROID = "0"; public final static String MOBILE_PLATFORM_ANDROID = "0";
@ -202,4 +202,9 @@ public class DeviceConstants {
public final static String WS_AMOUNT = "amount"; public final static String WS_AMOUNT = "amount";
public static final String ENGINE_MOB_ACTIVE_THREAD_KEY = "engine:mobile:activeThread"; public static final String ENGINE_MOB_ACTIVE_THREAD_KEY = "engine:mobile:activeThread";
public final static String ENGINE_DEVICE_TYPE_PC = "1"; // 引擎使用的设备类型PC
public final static String ENGINE_DEVICE_TYPE_MOBILE = "2"; // 引擎使用的设备类型,移动
} }

View File

@ -0,0 +1,21 @@
package net.northking.cctp.device.dto.device;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.ToString;
@Data
@ApiModel(value = "设备申请")
@ToString
public class ApplyDeviceDto {
@ApiModelProperty(value = "设备Id")
private String id;
@ApiModelProperty(value = "设备类型", notes = "1-pc2-移动")
private String type;
@ApiModelProperty(value = "token", notes = "可由请求方带上")
private String token;
}

View File

@ -0,0 +1,25 @@
package net.northking.cctp.device.dto.device;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.ToString;
import java.util.List;
@Data
@ApiModel(value = "设备批量申请dto")
@ToString
public class BatchApplyDeviceDto {
@ApiModelProperty(value = "申请人id")
private String id;
@ApiModelProperty(value = "使用来源engine为引擎使用0")
private String userBy;
@ApiModelProperty(value = "设备列表")
private List<ApplyDeviceDto> deviceList;
}

View File

@ -10,9 +10,7 @@ import net.northking.cctp.device.db.entity.CdDeviceStatus;
import net.northking.cctp.device.db.entity.CdDeviceToken; import net.northking.cctp.device.db.entity.CdDeviceToken;
import net.northking.cctp.device.db.service.CdDeviceStatusService; import net.northking.cctp.device.db.service.CdDeviceStatusService;
import net.northking.cctp.device.db.service.CdDeviceTokenService; import net.northking.cctp.device.db.service.CdDeviceTokenService;
import net.northking.cctp.device.dto.device.CdMobileDeviceExitDto; import net.northking.cctp.device.dto.device.*;
import net.northking.cctp.device.dto.device.DeviceInfoDto;
import net.northking.cctp.device.dto.device.DeviceLockDto;
import net.northking.cctp.device.dto.pcDevice.CdDeviceRemoteDto; import net.northking.cctp.device.dto.pcDevice.CdDeviceRemoteDto;
import net.northking.cctp.device.dto.pcDevice.CdPcDeviceExitDto; import net.northking.cctp.device.dto.pcDevice.CdPcDeviceExitDto;
import net.northking.cctp.device.dto.pcDevice.CdPcDeviceRemoteDto; import net.northking.cctp.device.dto.pcDevice.CdPcDeviceRemoteDto;
@ -161,4 +159,13 @@ public class DevicePubCtrl {
Map<String, List<String>> result = apiService.queryDeviceType(deviceIds); Map<String, List<String>> result = apiService.queryDeviceType(deviceIds);
return wrapper.success(result); return wrapper.success(result);
} }
@ApiOperation(value = "批量申请设备使用", notes = "token由请求方提供")
@PostMapping(value = "/deviceList/apply/batchWithToken")
public ResultWrapper<List<ApplyDeviceDto>> batchApplyWithToken(@RequestBody BatchApplyDeviceDto devices, HttpServletRequest request) {
logger.debug("批量申请设备(pub){}", devices);
ResultWrapper<List<ApplyDeviceDto>> wrapper = new ResultWrapper<>();
List<ApplyDeviceDto> resultList = apiService.deviceListApply(devices, request);
return wrapper.success(resultList);
}
} }