Commit 6b32114f by xmh

任务管理服务:

1. <feat> 添加 TaskController.overview 接口
2. <refactor> 替换使用 valEqual

运维服务:
1. <refactor> 录像上传的接口从 channel 中迁移到 VideoController 中

commons:
1. <feat> TaskStatus 添加 valEqual 方法
2. <feat> FanXingException 添加新构造方法
1 parent f35e7e20
......@@ -22,5 +22,8 @@ public enum TaskStatus {
this.val = val;
}
public boolean valEqual(Integer x) {
return x != null && x.equals(val);
}
}
......@@ -20,6 +20,10 @@ public class FanXingException extends RuntimeException implements Serializable {
public FanXingException() {}
public FanXingException(Throwable cause) {
super(cause);
}
public FanXingException(String message) {
super(message);
}
......
package com.viontech.fanxing.ops.controller.main;
import com.viontech.fanxing.ops.service.main.VideoService;
import com.viontech.keliu.util.JsonMessageUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.util.List;
/**
* .
*
* @author 谢明辉
* @date 2021/9/9
*/
@RestController
@RequestMapping("/video")
@Slf4j
public class VideoController {
@Resource
private VideoService videoService;
@PostMapping("/upload")
public Object uploadVideo(@RequestParam List<MultipartFile> files, @RequestParam(required = false) List<Long> tags) {
videoService.uploadVideo(files, tags);
return JsonMessageUtil.getSuccessJsonMsg("success");
}
}
......@@ -87,9 +87,4 @@ public class ChannelController extends ChannelBaseController {
return JsonMessageUtil.getSuccessJsonMsg(result);
}
@PostMapping("/video/upload")
public Object uploadVideo(@RequestParam List<MultipartFile> files, @RequestParam(required = false) List<Long> tags) {
channelService.uploadVideo(files, tags);
return JsonMessageUtil.getSuccessJsonMsg("success");
}
}
\ No newline at end of file
......@@ -3,9 +3,7 @@ package com.viontech.fanxing.ops.service.adapter;
import com.alibaba.fastjson.JSONObject;
import com.viontech.fanxing.commons.base.BaseService;
import com.viontech.fanxing.commons.model.Channel;
import com.viontech.fanxing.commons.vo.ChannelVo;
import com.viontech.fanxing.commons.vo.DictCodeVo;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
......@@ -15,6 +13,4 @@ public interface ChannelService extends BaseService<Channel> {
List<DictCodeVo> channelOrg(List<Channel> channels);
void uploadVideo(List<MultipartFile> files, List<Long> tags);
}
\ No newline at end of file
......@@ -4,9 +4,7 @@ import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.viontech.fanxing.commons.base.BaseMapper;
import com.viontech.fanxing.commons.base.BaseServiceImpl;
import com.viontech.fanxing.commons.config.VionConfig;
import com.viontech.fanxing.commons.constant.ChannelType;
import com.viontech.fanxing.commons.exception.FanXingException;
import com.viontech.fanxing.commons.model.*;
import com.viontech.fanxing.commons.vo.ChannelVo;
import com.viontech.fanxing.commons.vo.DictCodeVo;
......@@ -16,20 +14,17 @@ import com.viontech.fanxing.ops.service.adapter.ChannelTagService;
import com.viontech.fanxing.ops.service.adapter.DictCateService;
import com.viontech.fanxing.ops.service.adapter.DictCodeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.reactive.function.client.WebClient;
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.time.Duration;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@Service
......@@ -42,8 +37,6 @@ public class ChannelServiceImpl extends BaseServiceImpl<Channel> implements Chan
@Resource
private DictCateService dictCateService;
@Resource
private VionConfig vionConfig;
@Resource
private ChannelTagService channelTagService;
@Override
......@@ -177,50 +170,5 @@ public class ChannelServiceImpl extends BaseServiceImpl<Channel> implements Chan
return jsonObject;
}
/**
* 上传存储视频文件
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void uploadVideo(List<MultipartFile> files, List<Long> tags) {
for (MultipartFile file : files) {
String originalFilename = file.getOriginalFilename();
String basePath = vionConfig.getImage().getPath() + File.separator + "uploadVideo" + File.separator;
String extension = FilenameUtils.getExtension(originalFilename);
if (StringUtils.isBlank(extension) || !vionConfig.getSupportedVideoFormats().contains(extension.toLowerCase())) {
throw new FanXingException("不支持的视频格式:" + extension);
}
String unid = UUID.randomUUID().toString();
String filename = unid + "." + extension;
File video = new File(basePath + filename);
video.getParentFile().mkdirs();
try {
FileUtils.copyToFile(file.getInputStream(), video);
} catch (IOException e) {
throw new RuntimeException(e);
}
long videoLength = video.length();
long mbSize = videoLength / 1024 / 1024;
Channel channel = new Channel();
channel.setUnid(unid);
channel.setChannelUnid(unid);
channel.setDeviceUnid(unid);
channel.setName(originalFilename);
channel.setStreamPath(video.getPath());
channel.setType(ChannelType.FILE.value);
channel.setStreamType(ChannelType.STREAM_FILE.value);
channel.setPort(Math.toIntExact(mbSize));
channel = this.insertSelective(channel);
if (tags != null && tags.size() > 0) {
for (Long tagId : tags) {
ChannelTag channelTag = new ChannelTag();
channelTag.setChannelId(channel.getId());
channelTag.setTagId(tagId);
channelTagService.insertSelective(channelTag);
}
}
}
}
}
\ No newline at end of file
package com.viontech.fanxing.ops.service.main;
import com.viontech.fanxing.commons.config.VionConfig;
import com.viontech.fanxing.commons.constant.ChannelType;
import com.viontech.fanxing.commons.exception.FanXingException;
import com.viontech.fanxing.commons.model.Channel;
import com.viontech.fanxing.commons.model.ChannelTag;
import com.viontech.fanxing.ops.service.adapter.ChannelService;
import com.viontech.fanxing.ops.service.adapter.ChannelTagService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
/**
* .
*
* @author 谢明辉
* @date 2021/9/9
*/
@Slf4j
@Service
public class VideoService {
@Resource
private ChannelService channelService;
@Resource
private VionConfig vionConfig;
@Resource
private ChannelTagService channelTagService;
/**
* 上传存储视频文件
*/
@Transactional(rollbackFor = Exception.class)
public void uploadVideo(List<MultipartFile> files, List<Long> tags) {
for (MultipartFile file : files) {
String originalFilename = file.getOriginalFilename();
String basePath = vionConfig.getImage().getPath() + File.separator + "uploadVideo" + File.separator;
String extension = FilenameUtils.getExtension(originalFilename);
if (StringUtils.isBlank(extension) || !vionConfig.getSupportedVideoFormats().contains(extension.toLowerCase())) {
throw new FanXingException("不支持的视频格式:" + extension);
}
String unid = UUID.randomUUID().toString();
String filename = unid + "." + extension;
File video = new File(basePath + filename);
video.getParentFile().mkdirs();
try {
FileUtils.copyToFile(file.getInputStream(), video);
} catch (IOException e) {
throw new RuntimeException(e);
}
long videoLength = video.length();
long mbSize = videoLength / 1024 / 1024;
Channel channel = new Channel();
channel.setUnid(unid);
channel.setChannelUnid(unid);
channel.setDeviceUnid(unid);
channel.setName(originalFilename);
channel.setStreamPath(video.getPath());
channel.setType(ChannelType.FILE.value);
channel.setStreamType(ChannelType.STREAM_FILE.value);
channel.setPort(Math.toIntExact(mbSize));
channel = channelService.insertSelective(channel);
if (tags != null && tags.size() > 0) {
for (Long tagId : tags) {
ChannelTag channelTag = new ChannelTag();
channelTag.setChannelId(channel.getId());
channelTag.setTagId(tagId);
channelTagService.insertSelective(channelTag);
}
}
}
}
}
package com.viontech.fanxing.task.controller.web;
import com.alibaba.fastjson.JSONObject;
import com.viontech.fanxing.commons.base.BaseExample;
import com.viontech.fanxing.commons.model.TaskExample;
import com.viontech.fanxing.commons.vo.TaskVo;
......@@ -54,4 +55,10 @@ public class TaskController extends TaskBaseController {
}
return JsonMessageUtil.getSuccessJsonMsg("success");
}
@GetMapping("overview")
public JsonMessageUtil.JsonMessage overview() {
JSONObject overview = taskService.overview();
return JsonMessageUtil.getSuccessJsonMsg(overview);
}
}
\ No newline at end of file
package com.viontech.fanxing.task.service.adapter;
import com.alibaba.fastjson.JSONObject;
import com.viontech.fanxing.commons.base.BaseService;
import com.viontech.fanxing.commons.model.Task;
import com.viontech.fanxing.commons.vo.TaskVo;
......@@ -14,4 +15,6 @@ public interface TaskService extends BaseService<Task> {
void updateStatus(Long id, Integer status);
void startTask(Long id);
JSONObject overview();
}
\ No newline at end of file
package com.viontech.fanxing.task.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.viontech.fanxing.commons.base.BaseMapper;
import com.viontech.fanxing.commons.base.BaseServiceImpl;
import com.viontech.fanxing.commons.constant.TaskStatus;
import com.viontech.fanxing.commons.exception.FanXingException;
import com.viontech.fanxing.commons.model.Task;
import com.viontech.fanxing.commons.model.TaskExample;
import com.viontech.fanxing.commons.vo.TaskVo;
import com.viontech.fanxing.task.mapper.TaskMapper;
import com.viontech.fanxing.task.model.vaserver.VaServerInfo;
import com.viontech.fanxing.task.service.TaskDataService;
import com.viontech.fanxing.task.service.VAServerService;
import com.viontech.fanxing.task.service.adapter.TaskService;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RMap;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.time.Duration;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ExecutionException;
@Service
public class TaskServiceImpl extends BaseServiceImpl<Task> implements TaskService {
@Resource
private TaskMapper taskMapper;
@Resource
private TaskDataService taskDataService;
@Resource
private VAServerService vaServerService;
private final LoadingCache<String, JSONObject> OVERVIEW_CACHE = CacheBuilder.newBuilder()
.expireAfterWrite(Duration.ofMinutes(2))
.build(new CacheLoader<String, JSONObject>() {
@Override
public JSONObject load(String key) throws Exception {
List<Task> tasks = selectByExample(new TaskExample());
int resourceCount = 0;
int usedResourceCount = 0;
long taskCount = tasks.size();
long runningTaskCount = tasks.stream().filter(x -> TaskStatus.RUNNING.valEqual(x.getStatus())).count();
RMap<String, VaServerInfo> map = vaServerService.getVaServerRedisRepository().getVaServerInfoMap();
Collection<VaServerInfo> vaServerInfos = map.readAllValues();
for (VaServerInfo info : vaServerInfos) {
resourceCount += info.getVideoResource();
usedResourceCount += (info.getVideoResource() - info.getAvailableResources());
}
JSONObject result = new JSONObject();
result.put("resourceCount", resourceCount);
result.put("usedResourceCount", usedResourceCount);
result.put("taskCount", taskCount);
result.put("runningTaskCount", runningTaskCount);
return result;
}
});
@Override
public BaseMapper<Task> getMapper() {
......@@ -40,7 +83,10 @@ public class TaskServiceImpl extends BaseServiceImpl<Task> implements TaskServic
updateByPrimaryKeySelective(task);
task = selectByPrimaryKey(task.getId());
if (StringUtils.isNotBlank(task.getScene()) && task.getStoreConfigId() != null && !task.getStatus().equals(TaskStatus.AWAIT.val)) {
if (StringUtils.isNotBlank(task.getScene())
&& task.getStoreConfigId() != null
&& !TaskStatus.AWAIT.valEqual(task.getStatus())) {
taskDataService.updateTask(task);
}
return new TaskVo(task);
......@@ -81,4 +127,13 @@ public class TaskServiceImpl extends BaseServiceImpl<Task> implements TaskServic
taskDataService.addTask(task);
}
@Override
public JSONObject overview() {
try {
return OVERVIEW_CACHE.get("");
} catch (ExecutionException e) {
throw new FanXingException(e);
}
}
}
\ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!