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 { ...@@ -22,5 +22,8 @@ public enum TaskStatus {
this.val = val; 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 { ...@@ -20,6 +20,10 @@ public class FanXingException extends RuntimeException implements Serializable {
public FanXingException() {} public FanXingException() {}
public FanXingException(Throwable cause) {
super(cause);
}
public FanXingException(String message) { public FanXingException(String message) {
super(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 { ...@@ -87,9 +87,4 @@ public class ChannelController extends ChannelBaseController {
return JsonMessageUtil.getSuccessJsonMsg(result); 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 \ No newline at end of file
...@@ -3,9 +3,7 @@ package com.viontech.fanxing.ops.service.adapter; ...@@ -3,9 +3,7 @@ package com.viontech.fanxing.ops.service.adapter;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.viontech.fanxing.commons.base.BaseService; import com.viontech.fanxing.commons.base.BaseService;
import com.viontech.fanxing.commons.model.Channel; import com.viontech.fanxing.commons.model.Channel;
import com.viontech.fanxing.commons.vo.ChannelVo;
import com.viontech.fanxing.commons.vo.DictCodeVo; import com.viontech.fanxing.commons.vo.DictCodeVo;
import org.springframework.web.multipart.MultipartFile;
import java.util.List; import java.util.List;
...@@ -15,6 +13,4 @@ public interface ChannelService extends BaseService<Channel> { ...@@ -15,6 +13,4 @@ public interface ChannelService extends BaseService<Channel> {
List<DictCodeVo> channelOrg(List<Channel> channels); List<DictCodeVo> channelOrg(List<Channel> channels);
void uploadVideo(List<MultipartFile> files, List<Long> tags);
} }
\ No newline at end of file \ No newline at end of file
...@@ -4,9 +4,7 @@ import com.alibaba.fastjson.JSONArray; ...@@ -4,9 +4,7 @@ import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.viontech.fanxing.commons.base.BaseMapper; import com.viontech.fanxing.commons.base.BaseMapper;
import com.viontech.fanxing.commons.base.BaseServiceImpl; 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.constant.ChannelType;
import com.viontech.fanxing.commons.exception.FanXingException;
import com.viontech.fanxing.commons.model.*; import com.viontech.fanxing.commons.model.*;
import com.viontech.fanxing.commons.vo.ChannelVo; import com.viontech.fanxing.commons.vo.ChannelVo;
import com.viontech.fanxing.commons.vo.DictCodeVo; import com.viontech.fanxing.commons.vo.DictCodeVo;
...@@ -16,20 +14,17 @@ import com.viontech.fanxing.ops.service.adapter.ChannelTagService; ...@@ -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.DictCateService;
import com.viontech.fanxing.ops.service.adapter.DictCodeService; import com.viontech.fanxing.ops.service.adapter.DictCodeService;
import lombok.extern.slf4j.Slf4j; 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.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.ImmutablePair;
import org.springframework.stereotype.Service; 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 org.springframework.web.reactive.function.client.WebClient;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.time.Duration; 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; import java.util.stream.Collectors;
@Service @Service
...@@ -42,8 +37,6 @@ public class ChannelServiceImpl extends BaseServiceImpl<Channel> implements Chan ...@@ -42,8 +37,6 @@ public class ChannelServiceImpl extends BaseServiceImpl<Channel> implements Chan
@Resource @Resource
private DictCateService dictCateService; private DictCateService dictCateService;
@Resource @Resource
private VionConfig vionConfig;
@Resource
private ChannelTagService channelTagService; private ChannelTagService channelTagService;
@Override @Override
...@@ -177,50 +170,5 @@ public class ChannelServiceImpl extends BaseServiceImpl<Channel> implements Chan ...@@ -177,50 +170,5 @@ public class ChannelServiceImpl extends BaseServiceImpl<Channel> implements Chan
return jsonObject; 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 \ 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; package com.viontech.fanxing.task.controller.web;
import com.alibaba.fastjson.JSONObject;
import com.viontech.fanxing.commons.base.BaseExample; import com.viontech.fanxing.commons.base.BaseExample;
import com.viontech.fanxing.commons.model.TaskExample; import com.viontech.fanxing.commons.model.TaskExample;
import com.viontech.fanxing.commons.vo.TaskVo; import com.viontech.fanxing.commons.vo.TaskVo;
...@@ -54,4 +55,10 @@ public class TaskController extends TaskBaseController { ...@@ -54,4 +55,10 @@ public class TaskController extends TaskBaseController {
} }
return JsonMessageUtil.getSuccessJsonMsg("success"); return JsonMessageUtil.getSuccessJsonMsg("success");
} }
@GetMapping("overview")
public JsonMessageUtil.JsonMessage overview() {
JSONObject overview = taskService.overview();
return JsonMessageUtil.getSuccessJsonMsg(overview);
}
} }
\ No newline at end of file \ No newline at end of file
package com.viontech.fanxing.task.service.adapter; package com.viontech.fanxing.task.service.adapter;
import com.alibaba.fastjson.JSONObject;
import com.viontech.fanxing.commons.base.BaseService; import com.viontech.fanxing.commons.base.BaseService;
import com.viontech.fanxing.commons.model.Task; import com.viontech.fanxing.commons.model.Task;
import com.viontech.fanxing.commons.vo.TaskVo; import com.viontech.fanxing.commons.vo.TaskVo;
...@@ -14,4 +15,6 @@ public interface TaskService extends BaseService<Task> { ...@@ -14,4 +15,6 @@ public interface TaskService extends BaseService<Task> {
void updateStatus(Long id, Integer status); void updateStatus(Long id, Integer status);
void startTask(Long id); void startTask(Long id);
JSONObject overview();
} }
\ No newline at end of file \ No newline at end of file
package com.viontech.fanxing.task.service.impl; 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.BaseMapper;
import com.viontech.fanxing.commons.base.BaseServiceImpl; import com.viontech.fanxing.commons.base.BaseServiceImpl;
import com.viontech.fanxing.commons.constant.TaskStatus; 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.Task;
import com.viontech.fanxing.commons.model.TaskExample;
import com.viontech.fanxing.commons.vo.TaskVo; import com.viontech.fanxing.commons.vo.TaskVo;
import com.viontech.fanxing.task.mapper.TaskMapper; 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.TaskDataService;
import com.viontech.fanxing.task.service.VAServerService;
import com.viontech.fanxing.task.service.adapter.TaskService; import com.viontech.fanxing.task.service.adapter.TaskService;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RMap;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.Duration;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ExecutionException;
@Service @Service
public class TaskServiceImpl extends BaseServiceImpl<Task> implements TaskService { public class TaskServiceImpl extends BaseServiceImpl<Task> implements TaskService {
@Resource @Resource
private TaskMapper taskMapper; private TaskMapper taskMapper;
@Resource @Resource
private TaskDataService taskDataService; 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 @Override
public BaseMapper<Task> getMapper() { public BaseMapper<Task> getMapper() {
...@@ -40,7 +83,10 @@ public class TaskServiceImpl extends BaseServiceImpl<Task> implements TaskServic ...@@ -40,7 +83,10 @@ public class TaskServiceImpl extends BaseServiceImpl<Task> implements TaskServic
updateByPrimaryKeySelective(task); updateByPrimaryKeySelective(task);
task = selectByPrimaryKey(task.getId()); 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); taskDataService.updateTask(task);
} }
return new TaskVo(task); return new TaskVo(task);
...@@ -81,4 +127,13 @@ public class TaskServiceImpl extends BaseServiceImpl<Task> implements TaskServic ...@@ -81,4 +127,13 @@ public class TaskServiceImpl extends BaseServiceImpl<Task> implements TaskServic
taskDataService.addTask(task); 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 \ 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!